mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Regenerate snapshots & move fns around in writer
This commit is contained in:
parent
15802a27c0
commit
fa19fabd88
112 changed files with 618 additions and 4346 deletions
|
|
@ -2454,6 +2454,10 @@ pub fn pushTypesToSExprTree(self: *Self, maybe_expr_idx: ?CIR.Expr.Idx, tree: *S
|
|||
if (maybe_expr_idx) |expr_idx| {
|
||||
try self.pushExprTypesToSExprTree(expr_idx, tree);
|
||||
} else {
|
||||
// Create a TypeWriter to format the type
|
||||
var type_writer = try self.initTypeWriter();
|
||||
defer type_writer.deinit();
|
||||
|
||||
// Generate full type information for all definitions and expressions
|
||||
const root_begin = tree.beginNode();
|
||||
try tree.pushStaticAtom("inferred-types");
|
||||
|
|
@ -2483,12 +2487,8 @@ pub fn pushTypesToSExprTree(self: *Self, maybe_expr_idx: ?CIR.Expr.Idx, tree: *S
|
|||
const pattern_node_idx: CIR.Node.Idx = @enumFromInt(@intFromEnum(def.pattern));
|
||||
const pattern_region = self.store.getRegionAt(pattern_node_idx);
|
||||
|
||||
// Create a TypeWriter to format the type
|
||||
var type_writer = self.initTypeWriter() catch continue;
|
||||
defer type_writer.deinit();
|
||||
|
||||
// Write the type to the buffer
|
||||
type_writer.write(pattern_var) catch continue;
|
||||
try type_writer.write(pattern_var, .one_line);
|
||||
|
||||
// Add the pattern type entry
|
||||
const patt_begin = tree.beginNode();
|
||||
|
|
@ -2537,12 +2537,8 @@ pub fn pushTypesToSExprTree(self: *Self, maybe_expr_idx: ?CIR.Expr.Idx, tree: *S
|
|||
// Get the type variable for this statement
|
||||
const stmt_var = varFrom(stmt_idx);
|
||||
|
||||
// Create a TypeWriter to format the type
|
||||
var type_writer = self.initTypeWriter() catch continue;
|
||||
defer type_writer.deinit();
|
||||
|
||||
// Write the type to the buffer
|
||||
type_writer.write(stmt_var) catch continue;
|
||||
try type_writer.write(stmt_var, .one_line);
|
||||
|
||||
const type_str = type_writer.get();
|
||||
try tree.pushStringPair("type", type_str);
|
||||
|
|
@ -2566,12 +2562,8 @@ pub fn pushTypesToSExprTree(self: *Self, maybe_expr_idx: ?CIR.Expr.Idx, tree: *S
|
|||
// Get the type variable for this statement
|
||||
const stmt_var = varFrom(stmt_idx);
|
||||
|
||||
// Create a TypeWriter to format the type
|
||||
var type_writer = self.initTypeWriter() catch continue;
|
||||
defer type_writer.deinit();
|
||||
|
||||
// Write the type to the buffer
|
||||
type_writer.write(stmt_var) catch continue;
|
||||
try type_writer.write(stmt_var, .one_line);
|
||||
|
||||
const type_str = type_writer.get();
|
||||
try tree.pushStringPair("type", type_str);
|
||||
|
|
@ -2606,11 +2598,8 @@ pub fn pushTypesToSExprTree(self: *Self, maybe_expr_idx: ?CIR.Expr.Idx, tree: *S
|
|||
const expr_region = self.store.getRegionAt(expr_node_idx);
|
||||
|
||||
// Create a TypeWriter to format the type
|
||||
var type_writer = self.initTypeWriter() catch continue;
|
||||
defer type_writer.deinit();
|
||||
|
||||
// Write the type to the buffer
|
||||
type_writer.write(expr_var) catch continue;
|
||||
try type_writer.write(expr_var, .one_line);
|
||||
|
||||
// Add the expression type entry
|
||||
const expr_begin = tree.beginNode();
|
||||
|
|
@ -2643,7 +2632,7 @@ fn pushExprTypesToSExprTree(self: *Self, expr_idx: CIR.Expr.Idx, tree: *SExprTre
|
|||
defer type_writer.deinit();
|
||||
|
||||
// Write the type to the buffer
|
||||
try type_writer.write(expr_var);
|
||||
try type_writer.write(expr_var, .one_line);
|
||||
|
||||
// Add the formatted type to the S-expression tree
|
||||
const type_str = type_writer.get();
|
||||
|
|
|
|||
|
|
@ -588,8 +588,8 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addText("It has the type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_actual, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(owned_actual);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -599,8 +599,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText("But I expected it to be:");
|
||||
}
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_expected, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(owned_expected);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -707,8 +707,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText(expected_type_ordinal);
|
||||
try report.document.addText(" element has this type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -717,8 +717,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText(actual_type_ordinal);
|
||||
try report.document.addText(" element has this type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -791,8 +791,8 @@ pub const ReportBuilder = struct {
|
|||
// Add description
|
||||
try report.document.addText("Right now, it has the type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
|
||||
// Add explanation
|
||||
|
|
@ -914,8 +914,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText(" branch has this type:");
|
||||
}
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -930,8 +930,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText("But all the previous branches have this type:");
|
||||
}
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1015,8 +1015,8 @@ pub const ReportBuilder = struct {
|
|||
// Show the type of the invalid branch
|
||||
try report.document.addText("The first pattern has the type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1025,14 +1025,12 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addAnnotated("match", .keyword);
|
||||
try report.document.addText(" parenthesis has the type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
try report.document.addText("These two types can never match!");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -1124,8 +1122,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText(branch_ord);
|
||||
try report.document.addText(" pattern has this type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1136,8 +1134,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText("But the other pattern has this type:");
|
||||
}
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1145,8 +1143,6 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText("All patterns in an ");
|
||||
try report.document.addAnnotated("match", .keyword);
|
||||
try report.document.addText(" must have compatible types.");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -1235,8 +1231,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText(branch_ord);
|
||||
try report.document.addText(" branch has this type;");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1249,8 +1245,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText("But the previous branch has this type:");
|
||||
}
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1345,8 +1341,8 @@ pub const ReportBuilder = struct {
|
|||
}
|
||||
try report.document.addText(" side is:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1400,8 +1396,8 @@ pub const ReportBuilder = struct {
|
|||
// Show the invalid tag
|
||||
try report.document.addText("The tag is:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_tag_str, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_tag_str);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1414,15 +1410,15 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addText("But the nominal type needs it to be:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_tag_str, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_tag_str);
|
||||
} else {
|
||||
const expected_type = try report.addOwnedString(self.getFormattedString(types.expected_snapshot));
|
||||
|
||||
try report.document.addText("But the nominal type needs it to one of:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
|
||||
// Check if there's a tag with the same name in the list of possible tags
|
||||
|
||||
|
|
@ -1440,9 +1436,7 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addAnnotated("Hint:", .emphasized);
|
||||
try report.document.addReflowingText(" The nominal type has a tag with the same name, but different args:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(cur_expected_tag_str, .type_variable);
|
||||
try report.document.addCodeBlock(cur_expected_tag_str);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -1479,15 +1473,15 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addText("The record I found is:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
try report.document.addText("But the nominal type expects:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -1519,15 +1513,15 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addText("The tuple I found is:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
try report.document.addText("But the nominal type expects:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -1559,15 +1553,15 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addText("The value I found has type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
try report.document.addText("But the nominal type expects:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -1610,8 +1604,8 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addReflowingText("This argument has the type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1626,8 +1620,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addReflowingText(arg_index);
|
||||
try report.document.addReflowingText(" argument to be:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -1723,8 +1717,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText(first_arg_index);
|
||||
try report.document.addReflowingText(" argument has the type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(first_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(first_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1732,8 +1726,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addText(second_arg_index);
|
||||
try report.document.addReflowingText(" argument has the type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(second_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(second_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -1803,7 +1797,6 @@ pub const ReportBuilder = struct {
|
|||
self.source,
|
||||
self.module_env.getLineStarts(),
|
||||
);
|
||||
try report.document.addLineBreak();
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -1865,8 +1858,8 @@ pub const ReportBuilder = struct {
|
|||
// Show the function signature
|
||||
try report.document.addReflowingText("The function has the signature:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(fn_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(fn_type);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -1904,7 +1897,6 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addLineBreak();
|
||||
|
||||
try report.document.addReflowingText("Type aliases cannot be recursive. If you need a recursive type, use a nominal type (:=) instead of an alias (:).");
|
||||
try report.document.addLineBreak();
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -1938,7 +1930,6 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addLineBreak();
|
||||
|
||||
try report.document.addReflowingText("This syntax was used for abilities, which have been removed from Roc. Use method constraints like `where [a.methodName(args) -> ret]` instead.");
|
||||
try report.document.addLineBreak();
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -1982,9 +1973,7 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addReflowingText(", is:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(snapshot_str, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(snapshot_str);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -2045,8 +2034,7 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addReflowingText(", is:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(snapshot_str, .type_variable);
|
||||
try report.document.addCodeBlock(snapshot_str);
|
||||
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
|
@ -2126,8 +2114,8 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addReflowingText("The type is:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(snapshot_str, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(snapshot_str);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -2469,8 +2457,8 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addText("Its inferred type is:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_expected, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(owned_expected);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -2511,8 +2499,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addAnnotated("unsigned", .emphasized);
|
||||
try report.document.addReflowingText(":");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_expected, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(owned_expected);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -2549,8 +2537,7 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addText("Its inferred type is:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_expected, .type_variable);
|
||||
try report.document.addCodeBlock(owned_expected);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addReflowingText("Hint: Use a decimal type like ");
|
||||
|
|
@ -2576,8 +2563,7 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addText("Its inferred type is:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_expected, .type_variable);
|
||||
try report.document.addCodeBlock(owned_expected);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addReflowingText("Hint: Use a larger integer type or ");
|
||||
|
|
@ -2612,8 +2598,8 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addReflowingText("It has the type:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_expected, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(owned_expected);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -2683,8 +2669,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addLineBreak();
|
||||
|
||||
const expected_type = try report.addOwnedString(self.getFormattedString(types.expected_snapshot));
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(expected_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(expected_type);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
|
||||
|
|
@ -2699,9 +2685,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addLineBreak();
|
||||
|
||||
const actual_type = try report.addOwnedString(self.getFormattedString(types.actual_snapshot));
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(actual_type, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(actual_type);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -2724,9 +2709,7 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addAnnotated("app", .inline_code);
|
||||
try report.document.addReflowingText(" module to have a type alias named:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_name, .type_variable);
|
||||
try report.document.addCodeBlock(owned_name);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addReflowingText("But I could not find it.");
|
||||
|
|
@ -2756,8 +2739,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addAnnotated("app", .inline_code);
|
||||
try report.document.addReflowingText(" module to have a exported definition named:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_name, .type_variable);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(owned_name);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addReflowingText("But I could not find it.");
|
||||
|
|
@ -2802,8 +2785,8 @@ pub const ReportBuilder = struct {
|
|||
try report.document.addAnnotated("crash", .keyword);
|
||||
try report.document.addText(" happened with this message:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_message, .emphasized);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(owned_message);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
@ -2856,8 +2839,8 @@ pub const ReportBuilder = struct {
|
|||
|
||||
try report.document.addText("The evaluation failed with error:");
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addText(" ");
|
||||
try report.document.addAnnotated(owned_error_name, .emphasized);
|
||||
try report.document.addLineBreak();
|
||||
try report.document.addCodeBlock(owned_error_name);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ pub const Store = struct {
|
|||
|
||||
// Format this type and store the formatted string
|
||||
type_writer.reset();
|
||||
try type_writer.write(var_);
|
||||
try type_writer.write(var_, .wrap);
|
||||
const formatted = try self.gpa.dupe(u8, type_writer.get());
|
||||
try self.formatted_strings.put(self.gpa, snapshot_idx, formatted);
|
||||
|
||||
|
|
|
|||
|
|
@ -452,7 +452,7 @@ pub fn assertDefType(self: *TestEnv, target_def_name: []const u8, expected: []co
|
|||
.assign => |assign| {
|
||||
const def_name = idents.getText(assign.ident);
|
||||
if (std.mem.eql(u8, target_def_name, def_name)) {
|
||||
try self.type_writer.write(ModuleEnv.varFrom(def_idx));
|
||||
try self.type_writer.write(ModuleEnv.varFrom(def_idx), .wrap);
|
||||
try testing.expectEqualStrings(expected, self.type_writer.get());
|
||||
return;
|
||||
}
|
||||
|
|
@ -477,7 +477,7 @@ pub fn assertLastDefType(self: *TestEnv, expected: []const u8) !void {
|
|||
const last_def_idx = defs_slice[defs_slice.len - 1];
|
||||
const last_def_var = ModuleEnv.varFrom(last_def_idx);
|
||||
|
||||
try self.type_writer.write(last_def_var);
|
||||
try self.type_writer.write(last_def_var, .wrap);
|
||||
try testing.expectEqualStrings(expected, self.type_writer.get());
|
||||
}
|
||||
|
||||
|
|
@ -490,7 +490,7 @@ pub fn assertLastDefTypeContains(self: *TestEnv, expected_substring: []const u8)
|
|||
const last_def_idx = defs_slice[defs_slice.len - 1];
|
||||
const last_def_var = ModuleEnv.varFrom(last_def_idx);
|
||||
|
||||
try self.type_writer.write(last_def_var);
|
||||
try self.type_writer.write(last_def_var, .wrap);
|
||||
const type_str = self.type_writer.get();
|
||||
if (std.mem.indexOf(u8, type_str, expected_substring) == null) {
|
||||
std.debug.print("Expected type to contain '{s}', but got: {s}\n", .{ expected_substring, type_str });
|
||||
|
|
|
|||
|
|
@ -1,222 +0,0 @@
|
|||
//! Tests for cross-module type checking functionality.
|
||||
|
||||
const std = @import("std");
|
||||
const base = @import("base");
|
||||
const types_mod = @import("types");
|
||||
const can = @import("can");
|
||||
const Check = @import("../Check.zig");
|
||||
const TestEnv = @import("./TestEnv.zig");
|
||||
|
||||
const CIR = can.CIR;
|
||||
const Var = types_mod.Var;
|
||||
const Content = types_mod.Content;
|
||||
const Ident = base.Ident;
|
||||
const testing = std.testing;
|
||||
const ModuleEnv = can.ModuleEnv;
|
||||
const problem = @import("../problem.zig");
|
||||
const snapshot = @import("../snapshot.zig");
|
||||
const occurs = @import("../occurs.zig");
|
||||
const ProblemStore = problem.Store;
|
||||
const SnapshotStore = snapshot.Store;
|
||||
const UnifierScratch = @import("../unify.zig").Scratch;
|
||||
const OccursScratch = occurs.Scratch;
|
||||
const unify = @import("../unify.zig").unify;
|
||||
|
||||
test "cross-module - check type - monomorphic function passes" {
|
||||
const source_a =
|
||||
\\main! : Str -> Str
|
||||
\\main! = |s| s
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
// Str is auto-imported from Builtin module, so it prints as "Str"
|
||||
try test_env_a.assertLastDefType("Str -> Str");
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\main : Str
|
||||
\\main = A.main!("hello")
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
// Str is auto-imported from Builtin module, so it prints as "Str"
|
||||
try test_env_b.assertLastDefType("Str");
|
||||
}
|
||||
|
||||
test "cross-module - check type - monomorphic function fails" {
|
||||
const source_a =
|
||||
\\main! : Str -> Str
|
||||
\\main! = |s| s
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
try test_env_a.assertLastDefType("Str -> Str");
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\main : U8
|
||||
\\main = A.main!(1)
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertOneTypeError("TYPE MISMATCH");
|
||||
}
|
||||
|
||||
test "cross-module - check type - polymorphic function passes" {
|
||||
const source_a =
|
||||
\\main! : a -> a
|
||||
\\main! = |s| s
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
try test_env_a.assertLastDefType("a -> a");
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\main : Str
|
||||
\\main = A.main!("hello")
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
// Str is auto-imported from Builtin module, so it prints as "Str"
|
||||
try test_env_b.assertLastDefType("Str");
|
||||
}
|
||||
|
||||
test "cross-module - check type - polymorphic function with multiple uses passes" {
|
||||
const source_a =
|
||||
\\main! : a -> a
|
||||
\\main! = |s| s
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
try test_env_a.assertLastDefType("a -> a");
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\main : U64
|
||||
\\main = {
|
||||
\\ a = A.main!(10)
|
||||
\\ b = A.main!(15)
|
||||
\\ _c = A.main!("Hello")
|
||||
\\ a + b
|
||||
\\}
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertLastDefType("U64");
|
||||
}
|
||||
|
||||
test "cross-module - check type - static dispatch" {
|
||||
const source_a =
|
||||
\\A := [A(Str)].{
|
||||
\\ to_str : A -> Str
|
||||
\\ to_str = |A.A(val)| val
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
try test_env_a.assertDefType("A.to_str", "A -> Str");
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\a_val = A.A("hello")
|
||||
\\
|
||||
\\main = a_val.to_str()
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType("a_val", "A");
|
||||
try test_env_b.assertDefType("main", "Str");
|
||||
}
|
||||
|
||||
test "cross-module - check type - static dispatch - no annotation & indirection" {
|
||||
const source_a =
|
||||
\\A := [A(Str)].{
|
||||
\\ to_str = |A.A(val)| val
|
||||
\\ to_str2 = |x| x.to_str()
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
try test_env_a.assertDefType("A.to_str", "A -> Str");
|
||||
try test_env_a.assertDefType("A.to_str2", "a -> b where [a.to_str : a -> b ]");
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\val1 = A.A("hello")
|
||||
\\val2 = A.A("world")
|
||||
\\
|
||||
\\main = (val1.to_str(), val1.to_str2(), val2.to_str2())
|
||||
\\
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType("val1", "A");
|
||||
try test_env_b.assertDefType("val2", "A");
|
||||
try test_env_b.assertDefType("main", "(Str, Str, Str)");
|
||||
}
|
||||
|
||||
test "cross-module - check type - opaque types 1" {
|
||||
const source_a =
|
||||
\\A :: [A(Str)].{}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\a_val : A.A
|
||||
\\a_val = A("hello")
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertFirstTypeError("TYPE MISMATCH");
|
||||
}
|
||||
|
||||
test "cross-module - check type - opaque types 2" {
|
||||
const source_a =
|
||||
\\A :: [A(Str)].{}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\a_val = A.A("hello")
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertFirstTypeError("CANNOT USE OPAQUE NOMINAL TYPE");
|
||||
}
|
||||
|
||||
test "displayNameIsBetter - shorter names are preferred" {
|
||||
// Tests the core comparison logic used when multiple imports provide different
|
||||
// display names for the same type (e.g., `import Foo as F` and `import Foo as Foo`).
|
||||
// The shortest name wins for error message display. For equal lengths, the
|
||||
// lexicographically smaller name wins (deterministic regardless of import order).
|
||||
const displayNameIsBetter = Check.displayNameIsBetter;
|
||||
|
||||
// Shorter is better
|
||||
try testing.expect(displayNameIsBetter("T", "Type"));
|
||||
try testing.expect(displayNameIsBetter("AB", "ABC"));
|
||||
try testing.expect(!displayNameIsBetter("Type", "T"));
|
||||
try testing.expect(!displayNameIsBetter("ABC", "AB"));
|
||||
|
||||
// Equal length: lexicographically smaller wins
|
||||
try testing.expect(displayNameIsBetter("Abc", "Bbc")); // 'A' < 'B'
|
||||
try testing.expect(displayNameIsBetter("Aac", "Abc")); // 'a' < 'b' at position 1
|
||||
try testing.expect(!displayNameIsBetter("Bbc", "Abc"));
|
||||
try testing.expect(!displayNameIsBetter("Abc", "Aac"));
|
||||
|
||||
// Identical strings: no replacement
|
||||
try testing.expect(!displayNameIsBetter("Same", "Same"));
|
||||
try testing.expect(!displayNameIsBetter("", ""));
|
||||
}
|
||||
|
|
@ -1,254 +0,0 @@
|
|||
//! Integration tests for let-polymorphism that parse, canonicalize, and type-check
|
||||
//! actual code to ensure polymorphic values work correctly in practice.
|
||||
|
||||
const std = @import("std");
|
||||
const base = @import("base");
|
||||
const parse = @import("parse");
|
||||
const can = @import("can");
|
||||
const Check = @import("../Check.zig");
|
||||
const TestEnv = @import("./TestEnv.zig");
|
||||
|
||||
const Can = can.Can;
|
||||
const ModuleEnv = can.ModuleEnv;
|
||||
const CanonicalizedExpr = can.Can.CanonicalizedExpr;
|
||||
const testing = std.testing;
|
||||
const test_allocator = testing.allocator;
|
||||
|
||||
test "direct polymorphic identity usage" {
|
||||
const source =
|
||||
\\{
|
||||
\\ id = |x| x
|
||||
\\ a = id(1)
|
||||
\\ b = id("x")
|
||||
\\ { a, b }
|
||||
\\}
|
||||
;
|
||||
// The field 'a' has the same type as the dispatcher for from_numeral, so they should share the same name
|
||||
// Note: 'c' is used because 'a' and 'b' are already identifiers in the code
|
||||
try typeCheck(source, "{ a: c, b: Str } where [c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]");
|
||||
}
|
||||
|
||||
test "higher-order function with polymorphic identity" {
|
||||
const source =
|
||||
\\{
|
||||
\\ id = |x| x
|
||||
\\ f = |g, v| g(v)
|
||||
\\ a = f(id, 1)
|
||||
\\ b = f(id, "x")
|
||||
\\ { a, b }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(source, "{ a: c, b: Str } where [c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]");
|
||||
}
|
||||
|
||||
test "let-polymorphism with function composition" {
|
||||
const source =
|
||||
\\{
|
||||
\\ compose = |f, g| |x| f(g(x))
|
||||
\\ double = |x| x * 2
|
||||
\\ add_one = |x| x + 1
|
||||
\\ num_compose = compose(double, add_one)
|
||||
\\ result1 = num_compose(5)
|
||||
\\ { result1 }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(source, "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]");
|
||||
}
|
||||
|
||||
test "polymorphic empty list" {
|
||||
const source =
|
||||
\\{
|
||||
\\ empty = []
|
||||
\\ nums = [1, 2, 3]
|
||||
\\ strs = ["a", "b", "c"]
|
||||
\\ { empty, nums, strs }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(
|
||||
source,
|
||||
\\{ empty: List(_a), nums: List(b), strs: List(Str) }
|
||||
\\ where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]
|
||||
,
|
||||
);
|
||||
}
|
||||
|
||||
test "polymorphic cons function" {
|
||||
const source =
|
||||
\\{
|
||||
\\ cons = |x, xs| List.concat([x], xs)
|
||||
\\ list1 = cons(1, [2, 3])
|
||||
\\ list2 = cons("a", ["b", "c"])
|
||||
\\ { list1, list2 }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(
|
||||
source,
|
||||
\\{ list1: List(item), list2: List(Str) }
|
||||
\\ where [item.from_numeral : Numeral -> Try(item, [InvalidNumeral(Str)])]
|
||||
,
|
||||
);
|
||||
}
|
||||
|
||||
test "polymorphic record constructor" {
|
||||
const source =
|
||||
\\{
|
||||
\\ make_pair = |x, y| { first: x, second: y }
|
||||
\\ pair1 = make_pair(1, "a")
|
||||
\\ pair2 = make_pair("b", 42)
|
||||
\\ pair3 = make_pair(True, False)
|
||||
\\ { pair1, pair2, pair3 }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(
|
||||
source,
|
||||
\\{ pair1: { first: a, second: Str }, pair2: { first: Str, second: b }, pair3: { first: [True, .._others], second: [False, .._others2] } }
|
||||
\\ where [
|
||||
\\ a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
\\ b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
\\ ]
|
||||
,
|
||||
);
|
||||
}
|
||||
|
||||
test "polymorphic identity with various numeric types" {
|
||||
const source =
|
||||
\\{
|
||||
\\ id = |x| x
|
||||
\\ int_val = id(42)
|
||||
\\ float_val = id(3.14)
|
||||
\\ bool_val = id(True)
|
||||
\\ { int_val, float_val, bool_val }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(
|
||||
source,
|
||||
\\{ bool_val: [True, .._others], float_val: a, int_val: b }
|
||||
\\ where [
|
||||
\\ a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
\\ b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
\\ ]
|
||||
,
|
||||
);
|
||||
}
|
||||
|
||||
test "nested polymorphic data structures" {
|
||||
const source =
|
||||
\\{
|
||||
\\ make_box = |x| { value: x }
|
||||
\\ box1 = make_box(42)
|
||||
\\ box2 = make_box("hello")
|
||||
\\ nested = make_box(make_box(100))
|
||||
\\ { box1, box2, nested }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(
|
||||
source,
|
||||
|
||||
\\{ box1: { value: a }, box2: { value: Str }, nested: { value: { value: b } } }
|
||||
\\ where [
|
||||
\\ a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
\\ b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
\\ ]
|
||||
,
|
||||
);
|
||||
}
|
||||
|
||||
test "polymorphic function in let binding" {
|
||||
const source =
|
||||
\\{
|
||||
\\ result = {
|
||||
\\ id = |x| x
|
||||
\\ a = id(1)
|
||||
\\ b = id("test")
|
||||
\\ { a, b }
|
||||
\\ }
|
||||
\\ result
|
||||
\\}
|
||||
;
|
||||
try typeCheck(source, "{ a: c, b: Str } where [c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]");
|
||||
}
|
||||
|
||||
test "polymorphic swap function" {
|
||||
const source =
|
||||
\\{
|
||||
\\ swap = |pair| { first: pair.second, second: pair.first }
|
||||
\\ pair1 = { first: 1, second: "a" }
|
||||
\\ pair2 = { first: True, second: 42 }
|
||||
\\ swapped1 = swap(pair1)
|
||||
\\ swapped2 = swap(pair2)
|
||||
\\ { swapped1, swapped2 }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(
|
||||
source,
|
||||
\\{ swapped1: { first: Str, second: a }, swapped2: { first: b, second: [True, .._others] } }
|
||||
\\ where [
|
||||
\\ a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
\\ b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
\\ ]
|
||||
,
|
||||
);
|
||||
}
|
||||
|
||||
test "polymorphic option type simulation" {
|
||||
const source =
|
||||
\\{
|
||||
\\ none = { tag: "None" }
|
||||
\\ some = |x| { tag: "Some", value: x }
|
||||
\\ opt1 = some(42)
|
||||
\\ opt2 = some("hello")
|
||||
\\ opt3 = none
|
||||
\\ { opt1, opt2, opt3 }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(source,
|
||||
\\{ opt1: { tag: Str, value: a }, opt2: { tag: Str, value: Str }, opt3: { tag: Str } }
|
||||
\\ where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]
|
||||
);
|
||||
}
|
||||
|
||||
test "polymorphic const function" {
|
||||
const source =
|
||||
\\{
|
||||
\\ const = |x| |_| x
|
||||
\\ always5 = const(5)
|
||||
\\ alwaysHello = const("hello")
|
||||
\\ num = always5(99)
|
||||
\\ str = alwaysHello(True)
|
||||
\\ { num, str }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(
|
||||
source,
|
||||
"{ num: a, str: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]",
|
||||
);
|
||||
}
|
||||
|
||||
test "polymorphic pipe function" {
|
||||
const source =
|
||||
\\{
|
||||
\\ pipe = |x, f| f(x)
|
||||
\\ double = |n| n * 2
|
||||
\\ length = |_s| 5
|
||||
\\ num_result = pipe(21, double)
|
||||
\\ str_result = pipe("hello", length)
|
||||
\\ { num_result, str_result }
|
||||
\\}
|
||||
;
|
||||
try typeCheck(
|
||||
source,
|
||||
\\{ num_result: a, str_result: b }
|
||||
\\ where [
|
||||
\\ a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
\\ b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
\\ ]
|
||||
,
|
||||
);
|
||||
}
|
||||
|
||||
/// A unified helper to run the full pipeline: parse, canonicalize, and type-check source code.
|
||||
fn typeCheck(comptime source_expr: []const u8, expected_type: []const u8) !void {
|
||||
var test_env = try TestEnv.initExpr("Test", source_expr);
|
||||
defer test_env.deinit();
|
||||
return test_env.assertLastDefType(expected_type);
|
||||
}
|
||||
|
|
@ -177,13 +177,13 @@ test "numeric literal in comparison unifies with typed operand" {
|
|||
|
||||
// Check LHS type (should be I64)
|
||||
const lhs_var = ModuleEnv.varFrom(binop.lhs);
|
||||
try test_env.type_writer.write(lhs_var);
|
||||
try test_env.type_writer.write(lhs_var, .wrap);
|
||||
const lhs_type = test_env.type_writer.get();
|
||||
try testing.expectEqualStrings("I64", lhs_type);
|
||||
|
||||
// Check RHS type (the literal 42 - should also be I64 after unification)
|
||||
const rhs_var = ModuleEnv.varFrom(binop.rhs);
|
||||
try test_env.type_writer.write(rhs_var);
|
||||
try test_env.type_writer.write(rhs_var, .wrap);
|
||||
const rhs_type = test_env.type_writer.get();
|
||||
try testing.expectEqualStrings("I64", rhs_type);
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ test "polymorphic numeric in list used as List.get index unifies to U64 - regres
|
|||
|
||||
// Get the type from the expression (the literal 0)
|
||||
const expr_var = ModuleEnv.varFrom(def.expr);
|
||||
try test_env.type_writer.write(expr_var);
|
||||
try test_env.type_writer.write(expr_var, .wrap);
|
||||
const expr_type = test_env.type_writer.get();
|
||||
|
||||
// After unification with List.get's U64 parameter, should be U64
|
||||
|
|
@ -241,7 +241,7 @@ test "polymorphic numeric in list used as List.get index unifies to U64 - regres
|
|||
|
||||
// Also verify the pattern has the same type
|
||||
const pattern_var = ModuleEnv.varFrom(def.pattern);
|
||||
try test_env.type_writer.write(pattern_var);
|
||||
try test_env.type_writer.write(pattern_var, .wrap);
|
||||
const pattern_type = test_env.type_writer.get();
|
||||
try testing.expectEqualStrings("U64", pattern_type);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1884,7 +1884,7 @@ test "type_writer - recursion_var displays structure" {
|
|||
var writer = try TypeWriter.initFromParts(gpa, &env.module_env.types, env.module_env.getIdentStore(), null);
|
||||
defer writer.deinit();
|
||||
|
||||
const result = try writer.writeGet(rec_var);
|
||||
const result = try writer.writeGet(rec_var, .wrap);
|
||||
|
||||
// Should display as "{}" (the structure it points to)
|
||||
try std.testing.expectEqualStrings("{}", result);
|
||||
|
|
@ -1919,7 +1919,7 @@ test "type_writer - recursion_var with cycle displays correctly" {
|
|||
var writer = try TypeWriter.initFromParts(gpa, &env.module_env.types, env.module_env.getIdentStore(), null);
|
||||
defer writer.deinit();
|
||||
|
||||
const result = try writer.writeGet(rec_var);
|
||||
const result = try writer.writeGet(rec_var, .wrap);
|
||||
|
||||
// Should display as "List(...)" - the cycle is detected and shown as "..."
|
||||
try std.testing.expectEqualStrings("List(...)", result);
|
||||
|
|
@ -1956,7 +1956,7 @@ test "type_writer - nested recursion_var displays correctly" {
|
|||
var writer = try TypeWriter.initFromParts(gpa, &env.module_env.types, env.module_env.getIdentStore(), null);
|
||||
defer writer.deinit();
|
||||
|
||||
const result = try writer.writeGet(outer_rec_var);
|
||||
const result = try writer.writeGet(outer_rec_var, .wrap);
|
||||
|
||||
// Should display as "List({})" - following through the RecursionVars
|
||||
try std.testing.expectEqualStrings("List({})", result);
|
||||
|
|
@ -2031,7 +2031,7 @@ test "recursion_var - integration: deep recursion with RecursionVar prevents inf
|
|||
var writer = try TypeWriter.initFromParts(gpa, &env.module_env.types, env.module_env.getIdentStore(), null);
|
||||
defer writer.deinit();
|
||||
|
||||
const display = try writer.writeGet(var1);
|
||||
const display = try writer.writeGet(var1, .wrap);
|
||||
|
||||
// Should display "..." indicating cycle detection
|
||||
try std.testing.expect(std.mem.indexOf(u8, display, "...") != null);
|
||||
|
|
|
|||
|
|
@ -1,320 +0,0 @@
|
|||
//! Comprehensive tests for where clause type checking functionality.
|
||||
//!
|
||||
//! These tests cover:
|
||||
//! - Basic where clause parsing and type inference
|
||||
//! - Method constraints on type variables
|
||||
//! - Multiple constraints
|
||||
//! - Constraint satisfaction
|
||||
//! - Error cases
|
||||
|
||||
const std = @import("std");
|
||||
const TestEnv = @import("./TestEnv.zig");
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
// Basic where clause tests
|
||||
|
||||
test "where clause - basic method constraint infers correctly" {
|
||||
// Module A defines a type with to_str method
|
||||
const source_a =
|
||||
\\A := [Val(Str)].{
|
||||
\\ to_str : A -> Str
|
||||
\\ to_str = |A.Val(s)| s
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
// Module B uses A and defines a helper with where clause
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\helper : a -> Str where [a.to_str : a -> Str]
|
||||
\\helper = |x| x.to_str()
|
||||
\\
|
||||
\\main : Str
|
||||
\\main = helper(A.Val("hello"))
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType(
|
||||
"helper",
|
||||
"a -> Str where [a.to_str : a -> Str ]",
|
||||
);
|
||||
try test_env_b.assertDefType("main", "Str");
|
||||
}
|
||||
|
||||
test "where clause - polymorphic return type" {
|
||||
const source_a =
|
||||
\\A := [Val(Str)].{
|
||||
\\ to_str : A -> Str
|
||||
\\ to_str = |A.Val(s)| s
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\helper : a -> b where [a.to_str : a -> b]
|
||||
\\helper = |x| x.to_str()
|
||||
\\
|
||||
\\main : Str
|
||||
\\main = helper(A.Val("hello"))
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType(
|
||||
"helper",
|
||||
"a -> b where [a.to_str : a -> b ]",
|
||||
);
|
||||
try test_env_b.assertDefType("main", "Str");
|
||||
}
|
||||
|
||||
test "where clause - constraint with multiple args" {
|
||||
const source_a =
|
||||
\\A := [Box(Str)].{
|
||||
\\ transform : A, (Str -> Str) -> A
|
||||
\\ transform = |A.Box(s), fn| A.Box(fn(s))
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\modify : a, (Str -> Str) -> a where [a.transform : a, (Str -> Str) -> a]
|
||||
\\modify = |x, fn| x.transform(fn)
|
||||
\\
|
||||
\\main : A
|
||||
\\main = modify(A.Box("hello"), |s| s)
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType(
|
||||
"modify",
|
||||
"a, (Str -> Str) -> a where [a.transform : a, (Str -> Str) -> a ]",
|
||||
);
|
||||
try test_env_b.assertDefType("main", "A");
|
||||
}
|
||||
|
||||
// Multiple constraints tests
|
||||
|
||||
test "where clause - multiple constraints on same variable" {
|
||||
const source_a =
|
||||
\\A := [D(Str, U64)].{
|
||||
\\ to_str : A -> Str
|
||||
\\ to_str = |A.D(s, _)| s
|
||||
\\
|
||||
\\ to_u64 : A -> U64
|
||||
\\ to_u64 = |A.D(_, n)| n
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\both : a -> (Str, U64) where [a.to_str : a -> Str, a.to_u64 : a -> U64]
|
||||
\\both = |x| (x.to_str(), x.to_u64())
|
||||
\\
|
||||
\\main : (Str, U64)
|
||||
\\main = both(A.D("hello", 42))
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType(
|
||||
"both",
|
||||
"a -> (Str, U64) where [a.to_str : a -> Str, a.to_u64 : a -> U64 ]",
|
||||
);
|
||||
try test_env_b.assertDefType("main", "(Str, U64)");
|
||||
}
|
||||
|
||||
// Cross-module where clause tests
|
||||
|
||||
test "where clause - cross-module constraint satisfaction" {
|
||||
const source_a =
|
||||
\\A := [A(Str)].{
|
||||
\\ to_str : A -> Str
|
||||
\\ to_str = |A.A(val)| val
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
try test_env_a.assertDefType("A.to_str", "A -> Str");
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\helper : a -> Str where [a.to_str : a -> Str]
|
||||
\\helper = |x| x.to_str()
|
||||
\\
|
||||
\\main : Str
|
||||
\\main = helper(A.A("hello"))
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType(
|
||||
"helper",
|
||||
"a -> Str where [a.to_str : a -> Str ]",
|
||||
);
|
||||
try test_env_b.assertDefType("main", "Str");
|
||||
}
|
||||
|
||||
test "where clause - cross-module polymorphic constraint" {
|
||||
const source_a =
|
||||
\\A := [A(Str)].{
|
||||
\\ to_str = |A.A(val)| val
|
||||
\\ to_str2 = |x| x.to_str()
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
try test_env_a.assertDefType("A.to_str", "A -> Str");
|
||||
try test_env_a.assertDefType(
|
||||
"A.to_str2",
|
||||
"a -> b where [a.to_str : a -> b ]",
|
||||
);
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\main : Str
|
||||
\\main = (A.A("hello")).to_str2()
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType("main", "Str");
|
||||
}
|
||||
|
||||
// Nested/chained where clause tests
|
||||
|
||||
test "where clause - chained method calls" {
|
||||
const source_a =
|
||||
\\A := [Box(Str)].{
|
||||
\\ get_value : A -> Str
|
||||
\\ get_value = |A.Box(s)| s
|
||||
\\
|
||||
\\ transform : A, (Str -> Str) -> A
|
||||
\\ transform = |A.Box(s), fn| A.Box(fn(s))
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\chain : a, (Str -> Str) -> Str where [a.transform : a, (Str -> Str) -> a, a.get_value : a -> Str]
|
||||
\\chain = |x, fn| x.transform(fn).get_value()
|
||||
\\
|
||||
\\main : Str
|
||||
\\main = chain(A.Box("hello"), |s| s)
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType("main", "Str");
|
||||
}
|
||||
|
||||
// Error case tests
|
||||
|
||||
test "where clause - missing method on type" {
|
||||
const source_a =
|
||||
\\A := [Val(Str)].{}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\helper : a -> Str where [a.to_str : a -> Str]
|
||||
\\helper = |x| x.to_str()
|
||||
\\
|
||||
\\main = helper(A.Val("hello"))
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertFirstTypeError("MISSING METHOD");
|
||||
}
|
||||
|
||||
test "where clause - method signature mismatch" {
|
||||
const source_a =
|
||||
\\A := [Val(Str)].{
|
||||
\\ to_str : A -> U64
|
||||
\\ to_str = |_| 42
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\helper : a -> Str where [a.to_str : a -> Str]
|
||||
\\helper = |x| x.to_str()
|
||||
\\
|
||||
\\main = helper(A.Val("hello"))
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertFirstTypeError("TYPE MISMATCH");
|
||||
}
|
||||
|
||||
// Let polymorphism with where clauses
|
||||
|
||||
test "where clause - same type used multiple times with where constraint" {
|
||||
const source_a =
|
||||
\\A := [A(Str)].{
|
||||
\\ to_str : A -> Str
|
||||
\\ to_str = |A.A(s)| s
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\helper : a -> Str where [a.to_str : a -> Str]
|
||||
\\helper = |x| x.to_str()
|
||||
\\
|
||||
\\main : (Str, Str)
|
||||
\\main = (helper(A.A("hello")), helper(A.A("world")))
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType("main", "(Str, Str)");
|
||||
}
|
||||
|
||||
// Where clause without annotation (inferred)
|
||||
|
||||
test "where clause - inferred from method call without annotation" {
|
||||
const source_a =
|
||||
\\A := [Val(Str)].{
|
||||
\\ to_str : A -> Str
|
||||
\\ to_str = |A.Val(s)| s
|
||||
\\}
|
||||
;
|
||||
var test_env_a = try TestEnv.init("A", source_a);
|
||||
defer test_env_a.deinit();
|
||||
|
||||
const source_b =
|
||||
\\import A
|
||||
\\
|
||||
\\helper = |x| x.to_str()
|
||||
\\
|
||||
\\main : Str
|
||||
\\main = helper(A.Val("hello"))
|
||||
;
|
||||
var test_env_b = try TestEnv.initWithImport("B", source_b, "A", &test_env_a);
|
||||
defer test_env_b.deinit();
|
||||
try test_env_b.assertDefType(
|
||||
"helper",
|
||||
"a -> b where [a.to_str : a -> b ]",
|
||||
);
|
||||
try test_env_b.assertDefType("main", "Str");
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@ test "canonicalizeAndTypeCheckModule preserves Try types in type printing" {
|
|||
var type_writer = try env.initTypeWriter();
|
||||
defer type_writer.deinit();
|
||||
|
||||
try type_writer.write(map_result_var.?);
|
||||
try type_writer.write(map_result_var.?, .wrap);
|
||||
const type_str = type_writer.get();
|
||||
|
||||
// Check that the type contains "Try" and not "Error"
|
||||
|
|
|
|||
|
|
@ -181,9 +181,18 @@ pub fn reset(self: *TypeWriter) void {
|
|||
self.name_counters = std.EnumMap(TypeContext, u32).init(.{});
|
||||
}
|
||||
|
||||
fn hasSeenVar(self: *const TypeWriter, var_: Var) bool {
|
||||
for (self.seen.items) |seen| {
|
||||
if (seen == var_) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub const Format = enum { one_line, wrap };
|
||||
|
||||
/// Writes the current var into the the writers buffer and returns a bytes slice
|
||||
pub fn writeGet(self: *TypeWriter, var_: Var) std.mem.Allocator.Error![]const u8 {
|
||||
try self.write(var_);
|
||||
pub fn writeGet(self: *TypeWriter, var_: Var, format: Format) std.mem.Allocator.Error![]const u8 {
|
||||
try self.write(var_, format);
|
||||
return self.get();
|
||||
}
|
||||
|
||||
|
|
@ -195,14 +204,14 @@ pub fn get(self: *const TypeWriter) []const u8 {
|
|||
|
||||
/// Writes a type variable to the buffer, formatting it as a human-readable string.
|
||||
/// This clears any existing content in the buffer before writing.
|
||||
pub fn write(self: *TypeWriter, var_: Var) std.mem.Allocator.Error!void {
|
||||
pub fn write(self: *TypeWriter, var_: Var, format: Format) std.mem.Allocator.Error!void {
|
||||
self.reset();
|
||||
|
||||
var writer = self.buf.writer();
|
||||
try self.writeVar(&writer, var_, var_);
|
||||
|
||||
if (self.static_dispatch_constraints.items.len > 0) {
|
||||
try self.writeWhereClause(&writer, var_);
|
||||
try self.writeWhereClause(&writer, var_, format);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +220,7 @@ pub fn write(self: *TypeWriter, var_: Var) std.mem.Allocator.Error!void {
|
|||
/// 1. All on same line: "where [a.plus : a -> a, b.minus : b -> b]"
|
||||
/// 2. All on next line: "\n where [a.plus : a -> a, b.minus : b -> b]"
|
||||
/// 3. One per line: "\n where [\n a.plus : a -> a,\n b.minus : b -> b,\n ]"
|
||||
fn writeWhereClause(self: *TypeWriter, writer: *ByteWrite, root_var: Var) std.mem.Allocator.Error!void {
|
||||
fn writeWhereClause(self: *TypeWriter, writer: *ByteWrite, root_var: Var, format: Format) std.mem.Allocator.Error!void {
|
||||
const var_len = self.buf.items.len;
|
||||
var tmp_writer = self.buf_tmp.writer();
|
||||
|
||||
|
|
@ -287,7 +296,7 @@ fn writeWhereClause(self: *TypeWriter, writer: *ByteWrite, root_var: Var) std.me
|
|||
const line_len_if_all_on_next_line = 8 + constraints_len_if_on_same_line; // " where " = 8 chars
|
||||
|
||||
// Choose formatting style based on line length
|
||||
if (line_len_if_all_on_same_line <= 80) {
|
||||
if (line_len_if_all_on_same_line <= 80 or format == .one_line) {
|
||||
// All constraints fit on the same line as the type
|
||||
// Example: MyType where [plus : a, a -> a, minus : a, a -> a]
|
||||
_ = try writer.write(" where [");
|
||||
|
|
@ -322,116 +331,6 @@ fn writeWhereClause(self: *TypeWriter, writer: *ByteWrite, root_var: Var) std.me
|
|||
}
|
||||
}
|
||||
|
||||
fn generateNextName(self: *TypeWriter, writer: *ByteWrite) !void {
|
||||
// Generate name: a, b, ..., z, aa, ab, ..., az, ba, ...
|
||||
// Skip any names that already exist in the identifier store
|
||||
// We need at most one more name than the number of existing identifiers
|
||||
const max_attempts = self.idents.interner.entry_count + 1;
|
||||
var attempts: usize = 0;
|
||||
while (attempts < max_attempts) : (attempts += 1) {
|
||||
var n = self.next_name_index;
|
||||
self.next_name_index += 1;
|
||||
|
||||
var name_buf: [8]u8 = undefined;
|
||||
var name_len: usize = 0;
|
||||
|
||||
// Generate name in base-26: a, b, ..., z, aa, ab, ..., az, ba, ...
|
||||
while (name_len < name_buf.len) {
|
||||
name_buf[name_len] = @intCast('a' + (n % 26));
|
||||
name_len += 1;
|
||||
n = n / 26;
|
||||
if (n == 0) break;
|
||||
n -= 1;
|
||||
}
|
||||
|
||||
// Names are generated in reverse order, so reverse the buffer
|
||||
std.mem.reverse(u8, name_buf[0..name_len]);
|
||||
|
||||
// Check if this name already exists in the identifier store
|
||||
const candidate_name = name_buf[0..name_len];
|
||||
const exists = self.idents.interner.contains(candidate_name);
|
||||
|
||||
if (!exists) {
|
||||
// This name is available, use it
|
||||
_ = try writer.write(candidate_name);
|
||||
break;
|
||||
}
|
||||
// Name already exists, try the next one
|
||||
}
|
||||
|
||||
// This should never happen in practice, but let's handle it gracefully
|
||||
if (attempts >= max_attempts) {
|
||||
_ = try writer.write("var");
|
||||
try writer.print("{}", .{self.next_name_index});
|
||||
}
|
||||
}
|
||||
|
||||
fn generateContextualName(self: *TypeWriter, writer: *ByteWrite, context: TypeContext) std.mem.Allocator.Error!void {
|
||||
const base_name = switch (context) {
|
||||
.NumContent => "size",
|
||||
.ListContent => "elem",
|
||||
.RecordExtension => "others",
|
||||
.TagUnionExtension => "others",
|
||||
.RecordFieldContent => "field",
|
||||
.TupleFieldContent => "field",
|
||||
.FunctionArgument => "arg",
|
||||
.FunctionReturn => "ret",
|
||||
.General => {
|
||||
// Fall back to generic name generation
|
||||
try self.generateNextName(writer);
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
// Try to generate a name with increasing counters until we find one that doesn't collide
|
||||
var counter = self.name_counters.get(context) orelse 0;
|
||||
var found = false;
|
||||
|
||||
// We need at most as many attempts as there are existing identifiers
|
||||
const max_attempts = self.idents.interner.entry_count;
|
||||
var attempts: usize = 0;
|
||||
while (!found and attempts < max_attempts) : (attempts += 1) {
|
||||
var buf: [32]u8 = undefined;
|
||||
const candidate_name = if (counter == 0)
|
||||
base_name
|
||||
else blk: {
|
||||
const name = std.fmt.bufPrint(&buf, "{s}{}", .{ base_name, counter + 1 }) catch {
|
||||
// Buffer too small, fall back to generic name
|
||||
try self.generateNextName(writer);
|
||||
return;
|
||||
};
|
||||
break :blk name;
|
||||
};
|
||||
|
||||
// Check if this name already exists in the identifier store
|
||||
const exists = self.idents.interner.contains(candidate_name);
|
||||
|
||||
if (!exists) {
|
||||
// This name is available, write it to the buffer
|
||||
_ = try writer.write(candidate_name);
|
||||
found = true;
|
||||
} else {
|
||||
// Try next counter
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If we couldn't find a unique contextual name, fall back to generic names
|
||||
if (!found) {
|
||||
try self.generateNextName(writer);
|
||||
return;
|
||||
}
|
||||
|
||||
self.name_counters.put(context, counter + 1);
|
||||
}
|
||||
|
||||
fn hasSeenVar(self: *const TypeWriter, var_: Var) bool {
|
||||
for (self.seen.items) |seen| {
|
||||
if (seen == var_) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Convert a var to a type string
|
||||
fn writeVarWithContext(self: *TypeWriter, writer: *ByteWrite, var_: Var, context: TypeContext, root_var: Var) std.mem.Allocator.Error!void {
|
||||
if (@intFromEnum(var_) >= self.types.slots.backing.len()) {
|
||||
|
|
@ -1091,3 +990,106 @@ fn getDisplayName(self: *const TypeWriter, idx: Ident.Idx) []const u8 {
|
|||
|
||||
return name;
|
||||
}
|
||||
|
||||
fn generateContextualName(self: *TypeWriter, writer: *ByteWrite, context: TypeContext) std.mem.Allocator.Error!void {
|
||||
const base_name = switch (context) {
|
||||
.NumContent => "size",
|
||||
.ListContent => "elem",
|
||||
.RecordExtension => "others",
|
||||
.TagUnionExtension => "others",
|
||||
.RecordFieldContent => "field",
|
||||
.TupleFieldContent => "field",
|
||||
.FunctionArgument => "arg",
|
||||
.FunctionReturn => "ret",
|
||||
.General => {
|
||||
// Fall back to generic name generation
|
||||
try self.generateNextName(writer);
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
// Try to generate a name with increasing counters until we find one that doesn't collide
|
||||
var counter = self.name_counters.get(context) orelse 0;
|
||||
var found = false;
|
||||
|
||||
// We need at most as many attempts as there are existing identifiers
|
||||
const max_attempts = self.idents.interner.entry_count;
|
||||
var attempts: usize = 0;
|
||||
while (!found and attempts < max_attempts) : (attempts += 1) {
|
||||
var buf: [32]u8 = undefined;
|
||||
const candidate_name = if (counter == 0)
|
||||
base_name
|
||||
else blk: {
|
||||
const name = std.fmt.bufPrint(&buf, "{s}{}", .{ base_name, counter + 1 }) catch {
|
||||
// Buffer too small, fall back to generic name
|
||||
try self.generateNextName(writer);
|
||||
return;
|
||||
};
|
||||
break :blk name;
|
||||
};
|
||||
|
||||
// Check if this name already exists in the identifier store
|
||||
const exists = self.idents.interner.contains(candidate_name);
|
||||
|
||||
if (!exists) {
|
||||
// This name is available, write it to the buffer
|
||||
_ = try writer.write(candidate_name);
|
||||
found = true;
|
||||
} else {
|
||||
// Try next counter
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If we couldn't find a unique contextual name, fall back to generic names
|
||||
if (!found) {
|
||||
try self.generateNextName(writer);
|
||||
return;
|
||||
}
|
||||
|
||||
self.name_counters.put(context, counter + 1);
|
||||
}
|
||||
|
||||
fn generateNextName(self: *TypeWriter, writer: *ByteWrite) !void {
|
||||
// Generate name: a, b, ..., z, aa, ab, ..., az, ba, ...
|
||||
// Skip any names that already exist in the identifier store
|
||||
// We need at most one more name than the number of existing identifiers
|
||||
const max_attempts = self.idents.interner.entry_count + 1;
|
||||
var attempts: usize = 0;
|
||||
while (attempts < max_attempts) : (attempts += 1) {
|
||||
var n = self.next_name_index;
|
||||
self.next_name_index += 1;
|
||||
|
||||
var name_buf: [8]u8 = undefined;
|
||||
var name_len: usize = 0;
|
||||
|
||||
// Generate name in base-26: a, b, ..., z, aa, ab, ..., az, ba, ...
|
||||
while (name_len < name_buf.len) {
|
||||
name_buf[name_len] = @intCast('a' + (n % 26));
|
||||
name_len += 1;
|
||||
n = n / 26;
|
||||
if (n == 0) break;
|
||||
n -= 1;
|
||||
}
|
||||
|
||||
// Names are generated in reverse order, so reverse the buffer
|
||||
std.mem.reverse(u8, name_buf[0..name_len]);
|
||||
|
||||
// Check if this name already exists in the identifier store
|
||||
const candidate_name = name_buf[0..name_len];
|
||||
const exists = self.idents.interner.contains(candidate_name);
|
||||
|
||||
if (!exists) {
|
||||
// This name is available, use it
|
||||
_ = try writer.write(candidate_name);
|
||||
break;
|
||||
}
|
||||
// Name already exists, try the next one
|
||||
}
|
||||
|
||||
// This should never happen in practice, but let's handle it gracefully
|
||||
if (attempts >= max_attempts) {
|
||||
_ = try writer.write("var");
|
||||
try writer.print("{}", .{self.next_name_index});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,10 +44,12 @@ failPairDiffTypes = mkPair("1", 2)
|
|||
^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Pair(Str)_
|
||||
|
||||
Pair(Str)
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_Pair(U8)_
|
||||
|
||||
Pair(U8)
|
||||
|
||||
**MISSING METHOD**
|
||||
This **from_numeral** method is being called on a value whose type doesn't have that method:
|
||||
|
|
@ -59,7 +61,7 @@ failPairDiffTypes = mkPair("1", 2)
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -72,10 +74,12 @@ failPairDiffTypes2 = Pair.Pair(1, "str")
|
|||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Pair(Str)_
|
||||
|
||||
Pair(Str)
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_Pair(U64)_
|
||||
|
||||
Pair(U64)
|
||||
|
||||
**MISSING METHOD**
|
||||
This **from_numeral** method is being called on a value whose type doesn't have that method:
|
||||
|
|
@ -87,7 +91,7 @@ failPairDiffTypes2 = Pair.Pair(1, "str")
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -100,10 +104,12 @@ mkPairInvalid = |x, y| Pair.Pair(x, y)
|
|||
^^^^^^^^^^^^^^^
|
||||
|
||||
The tag is:
|
||||
_Pair a b_
|
||||
|
||||
Pair a b
|
||||
|
||||
But the nominal type needs it to be:
|
||||
_Pair a a_
|
||||
|
||||
Pair a a
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -173,10 +173,8 @@ test7 = 42->Ok
|
|||
(patt (type "b -> b"))
|
||||
(patt (type "b where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "b where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "[Ok(b), .._others]
|
||||
where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "[Ok(b), .._others]
|
||||
where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]")))
|
||||
(patt (type "[Ok(b), .._others] where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "[Ok(b), .._others] where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]")))
|
||||
(expressions
|
||||
(expr (type "Bool"))
|
||||
(expr (type "Bool"))
|
||||
|
|
@ -184,8 +182,6 @@ test7 = 42->Ok
|
|||
(expr (type "b -> b"))
|
||||
(expr (type "b where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "b where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "[Ok(b), .._others]
|
||||
where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "[Ok(b), .._others]
|
||||
where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))))
|
||||
(expr (type "[Ok(b), .._others] where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "[Ok(b), .._others] where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ Err(foo)??12>5*5 or 13+2<5 and 10-1>=16 or 12<=3/5
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Bool_
|
||||
Bool
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -186,13 +186,5 @@ EndOfFile,
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "(a, b, c, d, e, Bool, Bool, Bool, Bool, _field, _field2, f, Bool, Bool, Error)
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]),
|
||||
e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)]),
|
||||
f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "(a, b, c, d, e, Bool, Bool, Bool, Bool, _field, _field2, f, Bool, Bool, Error) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]), e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)]), f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -256,17 +256,10 @@ main = (captureSimple, captureMultiple, outerFn, useClosure)
|
|||
(patt (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "_arg -> (_arg2 -> a)
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "_arg -> (_arg2 -> a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "a -> (_arg -> a)"))
|
||||
(patt (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "(_arg -> a, _arg2 -> b, _arg3 -> (_arg4 -> c), _arg5 -> d)
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]),
|
||||
]")))
|
||||
(patt (type "(_arg -> a, _arg2 -> b, _arg3 -> (_arg4 -> c), _arg5 -> d) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)])]")))
|
||||
(expressions
|
||||
(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
|
|
@ -274,15 +267,8 @@ main = (captureSimple, captureMultiple, outerFn, useClosure)
|
|||
(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "_arg -> (_arg2 -> a)
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "_arg -> (_arg2 -> a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "a -> (_arg -> a)"))
|
||||
(expr (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "(_arg -> a, _arg2 -> b, _arg3 -> (_arg4 -> c), _arg5 -> d)
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]),
|
||||
]"))))
|
||||
(expr (type "(_arg -> a, _arg2 -> b, _arg3 -> (_arg4 -> c), _arg5 -> d) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)])]"))))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,12 @@ The second and third elements in this list have incompatible types:
|
|||
^^^^^^^ ^^^^^^^^^^^^
|
||||
|
||||
The second element has this type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
However, the third element has this type:
|
||||
_List(Str)_
|
||||
|
||||
List(Str)
|
||||
|
||||
All elements in a list must have compatible types.
|
||||
|
||||
|
|
@ -41,7 +43,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -55,7 +57,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -1227,14 +1227,7 @@ main = {
|
|||
(patt (type "(a -> a), a -> a"))
|
||||
(patt (type "(a -> b) -> ((b -> c) -> (a -> c))"))
|
||||
(patt (type "a, c -> d where [a.map : a, (b -> c) -> d]"))
|
||||
(patt (type "{ chained: a, final: a, id_results: (e, Str, [True, .._others]), processed: c, transformed: a }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)]),
|
||||
]")))
|
||||
(patt (type "{ chained: a, final: a, id_results: (e, Str, [True, .._others]), processed: c, transformed: a } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]")))
|
||||
(type_decls
|
||||
(nominal (type "Container(a)")
|
||||
(ty-header (name "Container")
|
||||
|
|
@ -1248,12 +1241,5 @@ main = {
|
|||
(expr (type "(a -> a), a -> a"))
|
||||
(expr (type "(a -> b) -> ((b -> c) -> (a -> c))"))
|
||||
(expr (type "a, c -> d where [a.map : a, (b -> c) -> d]"))
|
||||
(expr (type "{ chained: a, final: a, id_results: (e, Str, [True, .._others]), processed: c, transformed: a }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)]),
|
||||
]"))))
|
||||
(expr (type "{ chained: a, final: a, id_results: (e, Str, [True, .._others]), processed: c, transformed: a } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ x = 12.34()
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_({}) -> _ret_
|
||||
|
||||
({}) -> _ret
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -85,21 +85,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "(U8, I8, U16, I16, U32, I32, U64, I64, U128, I128, F32, F64, Dec, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]),
|
||||
e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)]),
|
||||
f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)]),
|
||||
g.from_numeral : Numeral -> Try(g, [InvalidNumeral(Str)]),
|
||||
h.from_numeral : Numeral -> Try(h, [InvalidNumeral(Str)]),
|
||||
i.from_numeral : Numeral -> Try(i, [InvalidNumeral(Str)]),
|
||||
j.from_numeral : Numeral -> Try(j, [InvalidNumeral(Str)]),
|
||||
k.from_numeral : Numeral -> Try(k, [InvalidNumeral(Str)]),
|
||||
l.from_numeral : Numeral -> Try(l, [InvalidNumeral(Str)]),
|
||||
m.from_numeral : Numeral -> Try(m, [InvalidNumeral(Str)]),
|
||||
n.from_numeral : Numeral -> Try(n, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "(U8, I8, U16, I16, U32, I32, U64, I64, U128, I128, F32, F64, Dec, a, b, c, d, e, f, g, h, i, j, k, l, m, n) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]), e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)]), f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)]), g.from_numeral : Numeral -> Try(g, [InvalidNumeral(Str)]), h.from_numeral : Numeral -> Try(h, [InvalidNumeral(Str)]), i.from_numeral : Numeral -> Try(i, [InvalidNumeral(Str)]), j.from_numeral : Numeral -> Try(j, [InvalidNumeral(Str)]), k.from_numeral : Numeral -> Try(k, [InvalidNumeral(Str)]), l.from_numeral : Numeral -> Try(l, [InvalidNumeral(Str)]), m.from_numeral : Numeral -> Try(m, [InvalidNumeral(Str)]), n.from_numeral : Numeral -> Try(n, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^
|
||||
|
||||
It has the type:
|
||||
_[Bool, .._others]_
|
||||
|
||||
[Bool, .._others]
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -55,7 +56,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_[LaunchNukeErr, .._others]_
|
||||
|
||||
[LaunchNukeErr, .._others]
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,13 @@ This expression is used in an unexpected way:
|
|||
^^^^
|
||||
|
||||
It has the type:
|
||||
_[C(a), ..[False, True, .._others]]
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]_
|
||||
|
||||
[C(a), ..[False, True, .._others]]
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]
|
||||
|
||||
But I expected it to be:
|
||||
_Bool_
|
||||
|
||||
Bool
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -55,6 +55,5 @@ EndOfFile,
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "{ answer: a, launchTheNukes!: {} -> _ret }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ answer: a, launchTheNukes!: {} -> _ret } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -41,6 +41,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "{ age: a, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -69,13 +69,9 @@ NO CHANGE
|
|||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "{ age: a, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ age: a, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]")))
|
||||
(patt (type "{ age: a, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ age: a, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]")))
|
||||
(expressions
|
||||
(expr (type "{ age: a, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))))
|
||||
(expr (type "{ age: a, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -119,21 +119,13 @@ NO CHANGE
|
|||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "{ age: a, city: Str, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ age: a, city: Str, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ age: a, city: Str, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ age: a, city: Str, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]")))
|
||||
(patt (type "{ age: a, city: Str, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ age: a, city: Str, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ age: a, city: Str, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ age: a, city: Str, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]")))
|
||||
(expressions
|
||||
(expr (type "{ age: a, city: Str, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, city: Str, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, city: Str, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, city: Str, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))))
|
||||
(expr (type "{ age: a, city: Str, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, city: Str, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, city: Str, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, city: Str, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -31,9 +31,8 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_[Ok([Just(a), .._others]), .._others2]
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]_
|
||||
|
||||
[Ok([Just(a), .._others]), .._others2]
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
@ -149,11 +148,5 @@ EndOfFile,
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "List([Err(Str), Just(a), Left(b), None, Nothing, Ok(Str), Right(c), Some([Ok([Just(d), .._others]), .._others2]), Try([Ok([Some([True, .._others3]), .._others4]), .._others5]), .._others6])
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "List([Err(Str), Just(a), Left(b), None, Nothing, Ok(Str), Right(c), Some([Ok([Just(d), .._others]), .._others2]), Try([Ok([Some([True, .._others3]), .._others4]), .._others5]), .._others6]) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -164,11 +164,5 @@ EndOfFile,
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "{ addOne: a -> a, errTag: [Err(Str), .._others], nested: [Some([Ok([Just(b), .._others2]), .._others3]), .._others4], noneTag: [None, .._others5], okTag: [Ok(Str), .._others6], result: Error, someTag: [Some(c), .._others7], tagList: List([Some(d), ..[None, .._others8]]) }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ addOne: a -> a, errTag: [Err(Str), .._others], nested: [Some([Ok([Just(b), .._others2]), .._others3]), .._others4], noneTag: [None, .._others5], okTag: [Ok(Str), .._others6], result: Error, someTag: [Some(c), .._others7], tagList: List([Some(d), ..[None, .._others8]]) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -34,6 +34,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "[Some(a), .._others]
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "[Some(a), .._others] where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -39,6 +39,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "(a, Str, [True, .._others])
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "(a, Str, [True, .._others]) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -39,6 +39,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "(a, Str, [True, .._others])
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "(a, Str, [True, .._others]) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "_arg, _arg2 -> a
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "_arg, _arg2 -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@ foo = if tru 0
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_{}_
|
||||
|
||||
{}
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -321,7 +321,6 @@ The where clause syntax _A_ is not supported:
|
|||
|
||||
This syntax was used for abilities, which have been removed from Roc. Use method constraints like `where [a.methodName(args) -> ret]` instead.
|
||||
|
||||
|
||||
**UNSUPPORTED WHERE CLAUSE**
|
||||
The where clause syntax _B_ is not supported:
|
||||
**everything.md:61:3:61:6:**
|
||||
|
|
@ -332,7 +331,6 @@ The where clause syntax _B_ is not supported:
|
|||
|
||||
This syntax was used for abilities, which have been removed from Roc. Use method constraints like `where [a.methodName(args) -> ret]` instead.
|
||||
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwImport,UpperIdent,KwExposing,OpenSquare,
|
||||
|
|
|
|||
|
|
@ -215,7 +215,6 @@ g : e -> e where [e.A, e.B]
|
|||
|
||||
This syntax was used for abilities, which have been removed from Roc. Use method constraints like `where [a.methodName(args) -> ret]` instead.
|
||||
|
||||
|
||||
**UNSUPPORTED WHERE CLAUSE**
|
||||
The where clause syntax _B_ is not supported:
|
||||
**everything.md:15:24:15:27:**
|
||||
|
|
@ -226,7 +225,6 @@ g : e -> e where [e.A, e.B]
|
|||
|
||||
This syntax was used for abilities, which have been removed from Roc. Use method constraints like `where [a.methodName(args) -> ret]` instead.
|
||||
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwImport,UpperIdent,KwExposing,OpenSquare,UpperIdent,Comma,UpperIdent,CloseSquare,
|
||||
|
|
|
|||
|
|
@ -214,7 +214,6 @@ g : e -> e where [e.A, e.B,]
|
|||
|
||||
This syntax was used for abilities, which have been removed from Roc. Use method constraints like `where [a.methodName(args) -> ret]` instead.
|
||||
|
||||
|
||||
**UNSUPPORTED WHERE CLAUSE**
|
||||
The where clause syntax _B_ is not supported:
|
||||
**everything.md:14:24:14:27:**
|
||||
|
|
@ -225,7 +224,6 @@ g : e -> e where [e.A, e.B,]
|
|||
|
||||
This syntax was used for abilities, which have been removed from Roc. Use method constraints like `where [a.methodName(args) -> ret]` instead.
|
||||
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwImport,UpperIdent,KwExposing,OpenSquare,UpperIdent,Comma,UpperIdent,Comma,CloseSquare,
|
||||
|
|
|
|||
|
|
@ -878,7 +878,6 @@ The type _List_ expects 1 argument, but got 0 instead.
|
|||
```
|
||||
|
||||
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
**fuzz_crash_019.md:39:2:39:3:**
|
||||
|
|
@ -888,7 +887,8 @@ This expression produces a value, but it's not being used:
|
|||
^
|
||||
|
||||
It has the type:
|
||||
_f where [f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)])]_
|
||||
|
||||
f where [f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)])]
|
||||
|
||||
**INCOMPATIBLE MATCH PATTERNS**
|
||||
The pattern in the fourth branch of this `match` differs from previous ones:
|
||||
|
|
@ -916,15 +916,15 @@ The pattern in the fourth branch of this `match` differs from previous ones:
|
|||
^^^^^
|
||||
|
||||
The fourth pattern has this type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But all the previous patterns have this type:
|
||||
_[Blue, .._others]_
|
||||
|
||||
[Blue, .._others]
|
||||
|
||||
All patterns in an `match` must have compatible types.
|
||||
|
||||
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
**fuzz_crash_019.md:1:1:1:1:**
|
||||
|
|
@ -934,7 +934,8 @@ This expression produces a value, but it's not being used:
|
|||
^
|
||||
|
||||
It has the type:
|
||||
__f_
|
||||
|
||||
_f
|
||||
|
||||
**TOO FEW ARGUMENTS**
|
||||
The function `me` expects 2 arguments, but 1 was provided:
|
||||
|
|
@ -946,7 +947,8 @@ The function `me` expects 2 arguments, but 1 was provided:
|
|||
```
|
||||
|
||||
The function has the signature:
|
||||
_[Blue, .._others], [Tb, .._others2] -> Error_
|
||||
|
||||
[Blue, .._others], [Tb, .._others2] -> Error
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -957,7 +959,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
**MISSING METHOD**
|
||||
This **from_numeral** method is being called on a value whose type doesn't have that method:
|
||||
|
|
@ -969,7 +972,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -987,11 +990,12 @@ This expression produces a value, but it's not being used:
|
|||
```
|
||||
|
||||
It has the type:
|
||||
_(f, Str, Error, [O, .._others], (Error, Error), List(j))
|
||||
where [
|
||||
f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)]),
|
||||
j.from_numeral : Numeral -> Try(j, [InvalidNumeral(Str)]),
|
||||
]_
|
||||
|
||||
(f, Str, Error, [O, .._others], (Error, Error), List(j))
|
||||
where [
|
||||
f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)]),
|
||||
j.from_numeral : Numeral -> Try(j, [InvalidNumeral(Str)]),
|
||||
]
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -1002,7 +1006,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Bool_
|
||||
|
||||
Bool
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -1013,7 +1018,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
__f_
|
||||
|
||||
_f
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -1024,7 +1030,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
__f_
|
||||
|
||||
_f
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -889,7 +889,6 @@ The type _List_ expects 1 argument, but got 0 instead.
|
|||
```
|
||||
|
||||
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
**fuzz_crash_020.md:39:2:39:3:**
|
||||
|
|
@ -899,7 +898,8 @@ This expression produces a value, but it's not being used:
|
|||
^
|
||||
|
||||
It has the type:
|
||||
_f where [f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)])]_
|
||||
|
||||
f where [f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)])]
|
||||
|
||||
**INCOMPATIBLE MATCH PATTERNS**
|
||||
The pattern in the fourth branch of this `match` differs from previous ones:
|
||||
|
|
@ -927,15 +927,15 @@ The pattern in the fourth branch of this `match` differs from previous ones:
|
|||
^^^^^
|
||||
|
||||
The fourth pattern has this type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But all the previous patterns have this type:
|
||||
_[Blue, .._others]_
|
||||
|
||||
[Blue, .._others]
|
||||
|
||||
All patterns in an `match` must have compatible types.
|
||||
|
||||
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
**fuzz_crash_020.md:1:1:1:1:**
|
||||
|
|
@ -945,7 +945,8 @@ This expression produces a value, but it's not being used:
|
|||
^
|
||||
|
||||
It has the type:
|
||||
__f_
|
||||
|
||||
_f
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -956,7 +957,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
**MISSING METHOD**
|
||||
This **from_numeral** method is being called on a value whose type doesn't have that method:
|
||||
|
|
@ -968,7 +970,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -986,11 +988,12 @@ This expression produces a value, but it's not being used:
|
|||
```
|
||||
|
||||
It has the type:
|
||||
_(f, Str, Error, [O, .._others], (Error, Error), List(j))
|
||||
where [
|
||||
f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)]),
|
||||
j.from_numeral : Numeral -> Try(j, [InvalidNumeral(Str)]),
|
||||
]_
|
||||
|
||||
(f, Str, Error, [O, .._others], (Error, Error), List(j))
|
||||
where [
|
||||
f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)]),
|
||||
j.from_numeral : Numeral -> Try(j, [InvalidNumeral(Str)]),
|
||||
]
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -1001,7 +1004,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Bool_
|
||||
|
||||
Bool
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -1012,7 +1016,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
__f_
|
||||
|
||||
_f
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -1023,7 +1028,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
__f_
|
||||
|
||||
_f
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -953,7 +953,8 @@ This `if` condition needs to be a _Bool_:
|
|||
^^^
|
||||
|
||||
Right now, it has the type:
|
||||
_U64_
|
||||
|
||||
U64
|
||||
|
||||
Every `if` condition must evaluate to a _Bool_–either `True` or `False`.
|
||||
|
||||
|
|
@ -1020,15 +1021,15 @@ The pattern in the fourth branch of this `match` differs from previous ones:
|
|||
^^^^^
|
||||
|
||||
The fourth pattern has this type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But all the previous patterns have this type:
|
||||
_[Red, ..[Blue, Green, .._others2]]_
|
||||
|
||||
[Red, ..[Blue, Green, .._others2]]
|
||||
|
||||
All patterns in an `match` must have compatible types.
|
||||
|
||||
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
**fuzz_crash_023.md:1:1:1:1:**
|
||||
|
|
@ -1038,7 +1039,8 @@ This expression produces a value, but it's not being used:
|
|||
^
|
||||
|
||||
It has the type:
|
||||
__d_
|
||||
|
||||
_d
|
||||
|
||||
**TOO FEW ARGUMENTS**
|
||||
The function `match_time` expects 2 arguments, but 1 was provided:
|
||||
|
|
@ -1050,7 +1052,8 @@ The function `match_time` expects 2 arguments, but 1 was provided:
|
|||
```
|
||||
|
||||
The function has the signature:
|
||||
_[Red, ..[Blue, Green, .._others2]], _arg -> Error_
|
||||
|
||||
[Red, ..[Blue, Green, .._others2]], _arg -> Error
|
||||
|
||||
**TYPE MISMATCH**
|
||||
This expression is used in an unexpected way:
|
||||
|
|
@ -1061,10 +1064,12 @@ This expression is used in an unexpected way:
|
|||
^
|
||||
|
||||
It has the type:
|
||||
_U64_
|
||||
|
||||
U64
|
||||
|
||||
But I expected it to be:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -1075,7 +1080,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^
|
||||
|
||||
It has the type:
|
||||
_[Blue, .._others2]_
|
||||
|
||||
[Blue, .._others2]
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -1086,7 +1092,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
__d_
|
||||
|
||||
_d
|
||||
|
||||
**TYPE MISMATCH**
|
||||
This expression is used in an unexpected way:
|
||||
|
|
@ -1148,10 +1155,12 @@ main! = |_| { # Yeah I can leave a comment here
|
|||
```
|
||||
|
||||
It has the type:
|
||||
_List(Error) => Error_
|
||||
|
||||
List(Error) => Error
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_List(Error) -> Error_
|
||||
|
||||
List(Error) -> Error
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -894,7 +894,6 @@ The type _List_ expects 1 argument, but got 0 instead.
|
|||
```
|
||||
|
||||
|
||||
|
||||
**INVALID IF CONDITION**
|
||||
This `if` condition needs to be a _Bool_:
|
||||
**fuzz_crash_027.md:50:5:**
|
||||
|
|
@ -904,7 +903,8 @@ This `if` condition needs to be a _Bool_:
|
|||
^^^
|
||||
|
||||
Right now, it has the type:
|
||||
_U64_
|
||||
|
||||
U64
|
||||
|
||||
Every `if` condition must evaluate to a _Bool_–either `True` or `False`.
|
||||
|
||||
|
|
@ -947,15 +947,15 @@ ist
|
|||
^^^^^
|
||||
|
||||
The third pattern has this type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But all the previous patterns have this type:
|
||||
_[Red, Blue, .._others2]_
|
||||
|
||||
[Red, Blue, .._others2]
|
||||
|
||||
All patterns in an `match` must have compatible types.
|
||||
|
||||
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
**fuzz_crash_027.md:1:1:1:1:**
|
||||
|
|
@ -965,7 +965,8 @@ This expression produces a value, but it's not being used:
|
|||
^
|
||||
|
||||
It has the type:
|
||||
__d_
|
||||
|
||||
_d
|
||||
|
||||
**TOO FEW ARGUMENTS**
|
||||
The function `match_time` expects 2 arguments, but 1 was provided:
|
||||
|
|
@ -977,7 +978,8 @@ The function `match_time` expects 2 arguments, but 1 was provided:
|
|||
```
|
||||
|
||||
The function has the signature:
|
||||
_[Blue, Red, .._others2], _arg -> Error_
|
||||
|
||||
[Blue, Red, .._others2], _arg -> Error
|
||||
|
||||
**MISSING METHOD**
|
||||
This **from_numeral** method is being called on a value whose type doesn't have that method:
|
||||
|
|
@ -989,7 +991,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -1003,7 +1005,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -1017,7 +1019,7 @@ The value before this **+** operator has a type that doesn't have a **plus** met
|
|||
|
||||
The value's type, which does not have a method named **plus**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:**The **+** operator calls a method named **plus** on the value preceding it, passing the value after the operator as the one argument.
|
||||
|
||||
|
|
@ -1033,10 +1035,12 @@ This expression is used in an unexpected way:
|
|||
```
|
||||
|
||||
It has the type:
|
||||
_[Stdoline!(Error), ..[Err(_d), Ok({ }), .._others2]]_
|
||||
|
||||
[Stdoline!(Error), ..[Err(_d), Ok({ }), .._others2]]
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_Try({ }, _d)_
|
||||
|
||||
Try({ }, _d)
|
||||
|
||||
**TYPE MISMATCH**
|
||||
This expression is used in an unexpected way:
|
||||
|
|
@ -1094,10 +1098,12 @@ e[, # afarg
|
|||
```
|
||||
|
||||
It has the type:
|
||||
_List(Error) => Error_
|
||||
|
||||
List(Error) => Error
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_List(Error) -> Error_
|
||||
|
||||
List(Error) -> Error
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -75,13 +75,9 @@ updated = {
|
|||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "{ age: a, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ age: a, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]")))
|
||||
(patt (type "{ age: a, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ age: a, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]")))
|
||||
(expressions
|
||||
(expr (type "{ age: a, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))))
|
||||
(expr (type "{ age: a, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))))
|
||||
~~~
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -40,7 +40,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Bool_
|
||||
Bool
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -54,8 +54,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_[A, .._others]_
|
||||
|
||||
[A, .._others]
|
||||
|
||||
**MISSING METHOD**
|
||||
This **from_numeral** method is being called on a value whose type doesn't have that method:
|
||||
|
|
@ -67,8 +66,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_[A, .._others]_
|
||||
|
||||
[A, .._others]
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -125,15 +125,7 @@ NO CHANGE
|
|||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "a -> Str
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
a.is_eq : a, a -> Bool,
|
||||
]")))
|
||||
(patt (type "a -> Str where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), a.is_eq : a, a -> Bool]")))
|
||||
(expressions
|
||||
(expr (type "a -> Str
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
a.is_eq : a, a -> Bool,
|
||||
]"))))
|
||||
(expr (type "a -> Str where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), a.is_eq : a, a -> Bool]"))))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -34,8 +34,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_[A, .._others]_
|
||||
|
||||
[A, .._others]
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -28,10 +28,12 @@ foo = if 1 A
|
|||
^^^^^^^
|
||||
|
||||
The `else` branch has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But the `then` branch has the type:
|
||||
_[A, .._others]_
|
||||
|
||||
[A, .._others]
|
||||
|
||||
All branches in an `if` must have compatible types.
|
||||
|
||||
|
|
@ -48,7 +50,7 @@ foo = if 1 A
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Bool_
|
||||
Bool
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -49,9 +49,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "[Ok(a), Err(b), .._others]
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "[Ok(a), Err(b), .._others] where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ foo = 42
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_BadType_
|
||||
BadType
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -36,10 +36,12 @@ value = "test"
|
|||
^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_GoodAlias_
|
||||
|
||||
GoodAlias
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -44,10 +44,12 @@ value = "test"
|
|||
^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_BadDerived_
|
||||
|
||||
BadDerived
|
||||
|
||||
**TYPE MISMATCH**
|
||||
This expression is used in an unexpected way:
|
||||
|
|
@ -58,10 +60,12 @@ goodValue = "test"
|
|||
^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_GoodDerived_
|
||||
|
||||
GoodDerived
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ foo = 42
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_BadType_
|
||||
BadType
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -144,10 +144,12 @@ bar = [1, 2, 3]
|
|||
^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_List(a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]_
|
||||
|
||||
List(a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_BadList_
|
||||
|
||||
BadList
|
||||
|
||||
**TYPE MISMATCH**
|
||||
This expression is used in an unexpected way:
|
||||
|
|
@ -158,11 +160,13 @@ baz = { field: "hi", other: 5 }
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_{ field: Str, other: a }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]_
|
||||
|
||||
{ field: Str, other: a }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_BadRecord_
|
||||
|
||||
BadRecord
|
||||
|
||||
**TYPE MISMATCH**
|
||||
This expression is used in an unexpected way:
|
||||
|
|
@ -173,10 +177,12 @@ qux = |x| x
|
|||
^^^^^
|
||||
|
||||
It has the type:
|
||||
_a -> a_
|
||||
|
||||
a -> a
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_BadFunction_
|
||||
|
||||
BadFunction
|
||||
|
||||
**TYPE MISMATCH**
|
||||
This expression is used in an unexpected way:
|
||||
|
|
@ -187,10 +193,12 @@ quux = ("hello", 42)
|
|||
^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_(Str, a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]_
|
||||
|
||||
(Str, a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_BadTuple_
|
||||
|
||||
BadTuple
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ value = 42
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_UsedType_
|
||||
UsedType
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ string_function = |x| x + 42
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ string_function = |x| x + 42
|
|||
|
||||
The value's type, which does not have a method named **plus**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:**The **+** operator calls a method named **plus** on the value preceding it, passing the value after the operator as the one argument.
|
||||
|
||||
|
|
|
|||
|
|
@ -83,10 +83,12 @@ The first and seventh arguments to `multi_arg_fn` must have compatible types, bu
|
|||
^^^^
|
||||
|
||||
The first argument has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But the seventh argument has the type:
|
||||
_[True, .._others]_
|
||||
|
||||
[True, .._others]
|
||||
|
||||
`multi_arg_fn` needs these arguments to have compatible types.
|
||||
|
||||
|
|
@ -100,7 +102,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -114,7 +116,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -1066,52 +1066,22 @@ main = |_| {
|
|||
(patt (type "List([True, False, .._others])"))
|
||||
(patt (type "List(List(_a))"))
|
||||
(patt (type "List(List(a)) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, items: List(_b) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, items: List(b) }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(patt (type "{ count: a, items: List(Str) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ data: List(_a), metadata: { description: Str, ratio: b, version: c } }
|
||||
where [
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(patt (type "{ data: List(a), metadata: { description: Str, ratio: b, version: c }, name: Str }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(patt (type "{ data: List(Str), metadata: { description: Str, ratio: a, version: b }, name: Str }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(patt (type "{ count: a, items: List(_b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, items: List(b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, items: List(Str) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ data: List(_a), metadata: { description: Str, ratio: b, version: c } } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ data: List(a), metadata: { description: Str, ratio: b, version: c }, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ data: List(Str), metadata: { description: Str, ratio: a, version: b }, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "a -> { value: a, wrapper: List(a) }"))
|
||||
(patt (type "{ value: a, wrapper: List(a) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ value: a, wrapper: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ value: Str, wrapper: List(Str) }"))
|
||||
(patt (type "{ value: a, wrapper: List(a) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ level1: { collection: List(_a), level2: { items: List(b), level3: { data: List(_c), value: b } } }, results: List({ data: List(d), tag: Str }) }
|
||||
where [
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(patt (type "{ value: a, wrapper: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ level1: { collection: List(_a), level2: { items: List(b), level3: { data: List(_c), value: b } } }, results: List({ data: List(d), tag: Str }) } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "List(a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ base: a, derived: List(a) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ computations: { from_frac: a, from_num: b, list_from_num: List(b) }, empty_lists: { in_list: List(List(_c)), in_record: { data: List(_d) }, raw: List(_e) }, numbers: { float: a, list: List(b), value: b }, strings: { list: List(Str), value: Str } }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(patt (type "{ base: a, derived: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ computations: { from_frac: a, from_num: b, list_from_num: List(b) }, empty_lists: { in_list: List(List(_c)), in_record: { data: List(_d) }, raw: List(_e) }, numbers: { float: a, list: List(b), value: b }, strings: { list: List(Str), value: Str } } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]")))
|
||||
(expressions
|
||||
(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
|
|
@ -1125,51 +1095,21 @@ main = |_| {
|
|||
(expr (type "List([True, False, .._others])"))
|
||||
(expr (type "List(List(_a))"))
|
||||
(expr (type "List(List(a)) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, items: List(_b) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, items: List(b) }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ count: a, items: List(Str) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ data: List(_a), metadata: { description: Str, ratio: b, version: c } }
|
||||
where [
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ data: List(a), metadata: { description: Str, ratio: b, version: c }, name: Str }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ data: List(Str), metadata: { description: Str, ratio: a, version: b }, name: Str }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ count: a, items: List(_b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, items: List(b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, items: List(Str) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ data: List(_a), metadata: { description: Str, ratio: b, version: c } } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ data: List(a), metadata: { description: Str, ratio: b, version: c }, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ data: List(Str), metadata: { description: Str, ratio: a, version: b }, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "a -> { value: a, wrapper: List(a) }"))
|
||||
(expr (type "{ value: a, wrapper: List(a) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ value: a, wrapper: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ value: Str, wrapper: List(Str) }"))
|
||||
(expr (type "{ value: a, wrapper: List(a) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ level1: { collection: List(_a), level2: { items: List(b), level3: { data: List(_c), value: b } } }, results: List({ data: List(d), tag: Str }) }
|
||||
where [
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ value: a, wrapper: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ level1: { collection: List(_a), level2: { items: List(b), level3: { data: List(_c), value: b } } }, results: List({ data: List(d), tag: Str }) } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "List(a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ base: a, derived: List(a) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ computations: { from_frac: a, from_num: b, list_from_num: List(b) }, empty_lists: { in_list: List(List(_c)), in_record: { data: List(_d) }, raw: List(_e) }, numbers: { float: a, list: List(b), value: b }, strings: { list: List(Str), value: Str } }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ base: a, derived: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ computations: { from_frac: a, from_num: b, list_from_num: List(b) }, empty_lists: { in_list: List(List(_c)), in_record: { data: List(_d) }, raw: List(_e) }, numbers: { float: a, list: List(b), value: b }, strings: { list: List(Str), value: Str } } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,5 @@ match [] {
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "{ empty: List(_a), ints: List(b), strs: List(Str) }
|
||||
where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ empty: List(_a), ints: List(b), strs: List(Str) } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ updated_mismatch = update_data(str_container, 99)
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -76,7 +76,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_{ ..a, data: b }, b -> { ..a, data: b }_
|
||||
|
||||
{ ..a, data: b }, b -> { ..a, data: b }
|
||||
|
||||
**MISSING METHOD**
|
||||
This **from_numeral** method is being called on a value whose type doesn't have that method:
|
||||
|
|
@ -88,8 +89,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_{ ..a, data: b }, b -> { ..a, data: b }_
|
||||
|
||||
{ ..a, data: b }, b -> { ..a, data: b }
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
@ -418,32 +418,18 @@ NO CHANGE
|
|||
(patt (type "Str"))
|
||||
(patt (type "List(_a)"))
|
||||
(patt (type "List(a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "a -> { count: b, data: a }
|
||||
where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, data: b }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(patt (type "{ count: a, data: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, data: List(_b) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "a -> { count: b, data: a } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, data: b } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, data: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, data: List(_b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ ..a, data: b }, b -> { ..a, data: b }"))
|
||||
(patt (type "{ count: a, data: b }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(patt (type "{ count: a, data: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, data: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, data: b } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, data: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ count: a, data: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "a -> { value: a }"))
|
||||
(patt (type "{ value: a } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ value: Str }"))
|
||||
(patt (type "{ value: List(a) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "{ value: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(patt (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]")))
|
||||
(expressions
|
||||
(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
|
|
@ -451,31 +437,17 @@ NO CHANGE
|
|||
(expr (type "Str"))
|
||||
(expr (type "List(_a)"))
|
||||
(expr (type "List(a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "a -> { count: b, data: a }
|
||||
where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, data: b }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ count: a, data: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, data: List(_b) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "a -> { count: b, data: a } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, data: b } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, data: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, data: List(_b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ ..a, data: b }, b -> { ..a, data: b }"))
|
||||
(expr (type "{ count: a, data: b }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ count: a, data: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, data: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, data: b } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, data: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ count: a, data: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "a -> { value: a }"))
|
||||
(expr (type "{ value: a } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ value: Str }"))
|
||||
(expr (type "{ value: List(a) }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ value: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -56,8 +56,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_[Answer, Zero, Greeting, .._others]_
|
||||
|
||||
[Answer, Zero, Greeting, .._others]
|
||||
|
||||
**MISSING METHOD**
|
||||
This **from_numeral** method is being called on a value whose type doesn't have that method:
|
||||
|
|
@ -69,7 +68,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -34,15 +34,15 @@ match ... {
|
|||
^^^^^
|
||||
|
||||
The third pattern has this type:
|
||||
_[Ok(_a), .._others]_
|
||||
|
||||
[Ok(_a), .._others]
|
||||
|
||||
But all the previous patterns have this type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
All patterns in an `match` must have compatible types.
|
||||
|
||||
|
||||
|
||||
**MISSING METHOD**
|
||||
This **from_numeral** method is being called on a value whose type doesn't have that method:
|
||||
**pattern_alternatives_mixed.md:2:10:2:11:**
|
||||
|
|
@ -53,7 +53,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -92,9 +92,5 @@ match (1, 2) {
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "(a, b)
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "(a, b) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -27,10 +27,12 @@ This expression is used in an unexpected way:
|
|||
^
|
||||
|
||||
It has the type:
|
||||
_{ c: Str }_
|
||||
|
||||
{ c: Str }
|
||||
|
||||
But I expected it to be:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -66,10 +66,12 @@ This expression is used in an unexpected way:
|
|||
^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But I expected it to be:
|
||||
_Bool_
|
||||
|
||||
Bool
|
||||
|
||||
**MISSING METHOD**
|
||||
This **from_numeral** method is being called on a value whose type doesn't have that method:
|
||||
|
|
@ -81,7 +83,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ boxed : Container(Foo.Bar)
|
|||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
UpperIdent,OpColonEqual,OpenSquare,UpperIdent,CloseSquare,Dot,OpenCurly,
|
||||
|
|
|
|||
|
|
@ -25,10 +25,12 @@ yellow = Color.Yellow
|
|||
^^^^^^^^^^^^
|
||||
|
||||
The tag is:
|
||||
_Yellow_
|
||||
|
||||
Yellow
|
||||
|
||||
But the nominal type needs it to one of:
|
||||
_[Blue, Green, Red]_
|
||||
|
||||
[Blue, Green, Red]
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -105,18 +105,5 @@ EndOfFile,
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "(a, b, c, d, e, f, g, h, i, j, k)
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]),
|
||||
e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)]),
|
||||
f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)]),
|
||||
g.from_numeral : Numeral -> Try(g, [InvalidNumeral(Str)]),
|
||||
h.from_numeral : Numeral -> Try(h, [InvalidNumeral(Str)]),
|
||||
i.from_numeral : Numeral -> Try(i, [InvalidNumeral(Str)]),
|
||||
j.from_numeral : Numeral -> Try(j, [InvalidNumeral(Str)]),
|
||||
k.from_numeral : Numeral -> Try(k, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "(a, b, c, d, e, f, g, h, i, j, k) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]), e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)]), f.from_numeral : Numeral -> Try(f, [InvalidNumeral(Str)]), g.from_numeral : Numeral -> Try(g, [InvalidNumeral(Str)]), h.from_numeral : Numeral -> Try(h, [InvalidNumeral(Str)]), i.from_numeral : Numeral -> Try(i, [InvalidNumeral(Str)]), j.from_numeral : Numeral -> Try(j, [InvalidNumeral(Str)]), k.from_numeral : Numeral -> Try(k, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -24,10 +24,12 @@ The first argument being passed to this function has the wrong type:
|
|||
^
|
||||
|
||||
This argument has the type:
|
||||
_I64_
|
||||
|
||||
I64
|
||||
|
||||
But the function needs the first argument to be:
|
||||
_Dec_
|
||||
|
||||
Dec
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ This **to_frac** method is being called on a value whose type doesn't have that
|
|||
|
||||
The value's type, which does not have a method named **to_frac**, is:
|
||||
|
||||
_U8_
|
||||
U8
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **to_frac** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ This **is_char_in_hex_range** method is being called on a value whose type doesn
|
|||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
U8
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -251,7 +251,7 @@ This **is_char_in_hex_range** method is being called on a value whose type doesn
|
|||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
U8
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ This **is_char_in_hex_range** method is being called on a value whose type doesn
|
|||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
U8
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ This **is_char_in_hex_range** method is being called on a value whose type doesn
|
|||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
U8
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -293,7 +293,7 @@ This **is_char_in_hex_range** method is being called on a value whose type doesn
|
|||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
U8
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -307,7 +307,7 @@ This **is_char_in_hex_range** method is being called on a value whose type doesn
|
|||
|
||||
The value's type, which does not have a method named **is_char_in_hex_range**, is:
|
||||
|
||||
_U8_
|
||||
U8
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **is_char_in_hex_range** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -321,7 +321,7 @@ This **is_named_color** method is being called on a value whose type doesn't hav
|
|||
|
||||
The value's type, which does not have a method named **is_named_color**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **is_named_color** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -335,7 +335,7 @@ expect rgb(124, 56, 245).to_str() == "rgb(124, 56, 245)"
|
|||
|
||||
The value's type, which does not have a method named **to_str**, is:
|
||||
|
||||
_Color_
|
||||
Color
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **to_str** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -349,7 +349,7 @@ expect rgba(124, 56, 245, 255).to_str() == "rgba(124, 56, 245, 1.0)"
|
|||
|
||||
The value's type, which does not have a method named **to_str**, is:
|
||||
|
||||
_Color_
|
||||
Color
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **to_str** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "{ age: a, email: Str, name: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, email: Str, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -99,6 +99,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "{ a: b, age: c, name: Str } -> { full_record: { a: b, age: c, name: Str }, greeting: Str, is_adult: Bool }
|
||||
where [c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ a: b, age: c, name: Str } -> { full_record: { a: b, age: c, name: Str }, greeting: Str, is_adult: Bool } where [c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -26,12 +26,11 @@ This **to_str** method is being called on a value whose type doesn't have that m
|
|||
|
||||
The value's type, which does not have a method named **to_str**, is:
|
||||
|
||||
_{ pair1: { first: a, second: Str }, pair2: { first: Str, second: b }, pair3: { first: [True, .._others], second: [False, .._others2] } }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]_
|
||||
|
||||
{ pair1: { first: a, second: Str }, pair2: { first: Str, second: b }, pair3: { first: [True, .._others], second: [False, .._others2] } }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
]
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -556,7 +556,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_[PascalCase, .._others]_
|
||||
|
||||
[PascalCase, .._others]
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -567,7 +568,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -578,7 +580,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^
|
||||
|
||||
It has the type:
|
||||
__a_
|
||||
|
||||
_a
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -589,7 +592,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -600,7 +604,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -457,7 +457,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -468,7 +469,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -84,6 +84,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "{ age: a, balance: Error, email: Error, name: Error, status: Str }
|
||||
where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
(expr (type "{ age: a, balance: Error, email: Error, name: Error, status: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -72,10 +72,5 @@ NO CHANGE
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "{ active: Error, age: a, balance: b, name: Str, scores: List(c) }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ active: Error, age: a, balance: b, name: Str, scores: List(c) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -137,10 +137,5 @@ EndOfFile,
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "{ address: { city: Str, coordinates: { lat: a, lng: b }, street: Str }, contact: { email: Str, phone: { home: Str, work: Str } }, person: { age: c, name: Str } }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ address: { city: Str, coordinates: { lat: a, lng: b }, street: Str }, contact: { email: Str, phone: { home: Str, work: Str } }, person: { age: c, name: Str } } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -234,10 +234,5 @@ EndOfFile,
|
|||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr (type "{ callback: a -> a, metadata: [Ok({ permissions: List([Read, Write, Admin, .._others]), tags: List(Str) }), .._others2], name: Str, nested: { items: List([Some(Str), ..[None, .._others3]]), result: [Success({ data: List(b), timestamp: Str }), .._others4] }, preferences: { notifications: [Email(Str), .._others5], theme: [Dark, .._others6] }, scores: List(c), status: [Active({ since: Str }), .._others7] }
|
||||
where [
|
||||
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
|
||||
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
|
||||
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
|
||||
]"))
|
||||
(expr (type "{ callback: a -> a, metadata: [Ok({ permissions: List([Read, Write, Admin, .._others]), tags: List(Str) }), .._others2], name: Str, nested: { items: List([Some(Str), ..[None, .._others3]]), result: [Success({ data: List(b), timestamp: Str }), .._others4] }, preferences: { notifications: [Email(Str), .._others5], theme: [Dark, .._others6] }, scores: List(c), status: [Active({ since: Str }), .._others7] } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ This **update_strr** method is being called on a value whose type doesn't have t
|
|||
|
||||
The value's type, which does not have a method named **update_strr**, is:
|
||||
|
||||
_Adv_
|
||||
Adv
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **update_strr** associated with it in the type's declaration.
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ This **update** method is being called on a value whose type doesn't have that m
|
|||
|
||||
The value's type, which does not have a method named **update**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **update** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ result1 = a + b
|
|||
|
||||
The value's type, which does not have a method named **plus**, is:
|
||||
|
||||
_MyType_
|
||||
MyType
|
||||
|
||||
**Hint:**The **+** operator calls a method named **plus** on the value preceding it, passing the value after the operator as the one argument.
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ result2 = a.plus(b)
|
|||
|
||||
The value's type, which does not have a method named **plus**, is:
|
||||
|
||||
_MyType_
|
||||
MyType
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **plus** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -22,10 +22,12 @@ y = "value: ${x}"
|
|||
^
|
||||
|
||||
It has the type:
|
||||
_U8_
|
||||
|
||||
U8
|
||||
|
||||
But I expected it to be:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -844,7 +844,8 @@ This `if` condition needs to be a _Bool_:
|
|||
^^^
|
||||
|
||||
Right now, it has the type:
|
||||
_U64_
|
||||
|
||||
U64
|
||||
|
||||
Every `if` condition must evaluate to a _Bool_–either `True` or `False`.
|
||||
|
||||
|
|
@ -911,15 +912,15 @@ The pattern in the fourth branch of this `match` differs from previous ones:
|
|||
^^^^^
|
||||
|
||||
The fourth pattern has this type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
But all the previous patterns have this type:
|
||||
_[Red, ..[Blue, Green, .._others2]]_
|
||||
|
||||
[Red, ..[Blue, Green, .._others2]]
|
||||
|
||||
All patterns in an `match` must have compatible types.
|
||||
|
||||
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
**syntax_grab_bag.md:1:1:1:1:**
|
||||
|
|
@ -929,7 +930,8 @@ This expression produces a value, but it's not being used:
|
|||
^
|
||||
|
||||
It has the type:
|
||||
__d_
|
||||
|
||||
_d
|
||||
|
||||
**TOO FEW ARGUMENTS**
|
||||
The function `match_time` expects 2 arguments, but 1 was provided:
|
||||
|
|
@ -941,7 +943,8 @@ The function `match_time` expects 2 arguments, but 1 was provided:
|
|||
```
|
||||
|
||||
The function has the signature:
|
||||
_[Red, ..[Blue, Green, .._others2]], _arg -> Error_
|
||||
|
||||
[Red, ..[Blue, Green, .._others2]], _arg -> Error
|
||||
|
||||
**TYPE MISMATCH**
|
||||
This expression is used in an unexpected way:
|
||||
|
|
@ -952,10 +955,12 @@ This expression is used in an unexpected way:
|
|||
^
|
||||
|
||||
It has the type:
|
||||
_U64_
|
||||
|
||||
U64
|
||||
|
||||
But I expected it to be:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
**UNUSED VALUE**
|
||||
This expression produces a value, but it's not being used:
|
||||
|
|
@ -966,7 +971,8 @@ This expression produces a value, but it's not being used:
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
__d_
|
||||
|
||||
_d
|
||||
|
||||
**TYPE MISMATCH**
|
||||
This expression is used in an unexpected way:
|
||||
|
|
@ -1028,10 +1034,12 @@ main! = |_| { # Yeah I can leave a comment here
|
|||
```
|
||||
|
||||
It has the type:
|
||||
_List(Error) => Error_
|
||||
|
||||
List(Error) => Error
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_List(Error) -> Error_
|
||||
|
||||
List(Error) -> Error
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@ The function `map_pair` expects 3 arguments, but 4 were provided:
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The function has the signature:
|
||||
_Pair(a, b), (a -> c), (b -> d) -> Pair(c, d)_
|
||||
|
||||
Pair(a, b), (a -> c), (b -> d) -> Pair(c, d)
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ This **from_numeral** method is being called on a value whose type doesn't have
|
|||
|
||||
The value's type, which does not have a method named **from_numeral**, is:
|
||||
|
||||
_Str_
|
||||
Str
|
||||
|
||||
**Hint:** For this to work, the type would need to have a method named **from_numeral** associated with it in the type's declaration.
|
||||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,12 @@ The first argument being passed to this function has the wrong type:
|
|||
^^^^^^^^^
|
||||
|
||||
This argument has the type:
|
||||
_List(Str)_
|
||||
|
||||
List(Str)
|
||||
|
||||
But `f` needs the first argument to be:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ The function `identity` expects 1 argument, but 2 were provided:
|
|||
^^^^^^^^^^^^^^
|
||||
|
||||
The function has the signature:
|
||||
_(a, b) -> (a, b)_
|
||||
|
||||
(a, b) -> (a, b)
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -32,10 +32,12 @@ composed = |n| get_value(make_record(n))
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It has the type:
|
||||
_List(a)_
|
||||
|
||||
List(a)
|
||||
|
||||
But the type annotation says it should have the type:
|
||||
_Str_
|
||||
|
||||
Str
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ main = swap(1, 2)
|
|||
^^^^^^^^^^
|
||||
|
||||
The function has the signature:
|
||||
_(a, b) -> (b, a)_
|
||||
|
||||
(a, b) -> (b, a)
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ main! = |_| swapPair(1, 2)
|
|||
^^^^^^^^^^^^^^
|
||||
|
||||
The function has the signature:
|
||||
_Pair(a, b) -> Pair(b, a)_
|
||||
|
||||
Pair(a, b) -> Pair(b, a)
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue