From 8ea4eaa48802327f98cecaeb9f588bc9b1941b22 Mon Sep 17 00:00:00 2001 From: Jared Ramirez Date: Tue, 21 Oct 2025 08:54:29 -0400 Subject: [PATCH] Typos + snapshot problems --- src/canonicalize/Can.zig | 8 +- src/canonicalize/Statement.zig | 2 +- src/check/Check.zig | 34 ++--- src/check/snapshot.zig | 30 ++--- src/check/test/type_checking_integration.zig | 2 +- src/types/TypeWriter.zig | 16 +-- test/snapshots/static_dispatch/Adv.md | 124 +++++++++++++++++++ 7 files changed, 164 insertions(+), 52 deletions(-) diff --git a/src/canonicalize/Can.zig b/src/canonicalize/Can.zig index d8da60253e..37a643f3f4 100644 --- a/src/canonicalize/Can.zig +++ b/src/canonicalize/Can.zig @@ -603,7 +603,7 @@ fn processAssociatedItemsSecondPass( // then just add the annotation independently // TODO: Capture diagnostic that this anno doesn't - // have a corrosponding def + // have a corresponding def const region = self.parse_ir.tokenizedRegionToRegion(ta.region); @@ -1030,7 +1030,7 @@ pub fn canonicalizeFile( // then just add the annotation independently // TODO: Capture diagnostic that this anno doesn't - // have a corrosponding def + // have a corresponding def const type_anno_stmt = Statement{ .s_type_anno = .{ .name = name_ident, @@ -6399,7 +6399,7 @@ pub fn canonicalizeBlockStatement(self: *Self, ast_stmt: AST.Statement, ast_stmt // then just add the annotation independently // TODO: Capture diagnostic that this anno doesn't - // have a corrosponding def + // have a corresponding def const stmt_idx = try self.env.addStatement(Statement{ .s_type_anno = .{ @@ -6416,7 +6416,7 @@ pub fn canonicalizeBlockStatement(self: *Self, ast_stmt: AST.Statement, ast_stmt // then just add the annotation independently // TODO: Capture diagnostic that this anno doesn't - // have a corrosponding def + // have a corresponding def const stmt_idx = try self.env.addStatement(Statement{ .s_type_anno = .{ diff --git a/src/canonicalize/Statement.zig b/src/canonicalize/Statement.zig index a15347719a..abcfec2b4a 100644 --- a/src/canonicalize/Statement.zig +++ b/src/canonicalize/Statement.zig @@ -152,7 +152,7 @@ pub const Statement = union(enum) { /// /// Typically an annotation will be stored on the `Def` and will not be /// in the tree independently. But if there is an annotation without a - /// corrosponding we represent it with this node + /// corresponding we represent it with this node s_type_anno: struct { name: Ident.Idx, anno: CIR.TypeAnno.Idx, diff --git a/src/check/Check.zig b/src/check/Check.zig index 5552e939eb..ed6578865c 100644 --- a/src/check/Check.zig +++ b/src/check/Check.zig @@ -96,7 +96,7 @@ static_dispatch_method_name_buf: std.ArrayList(u8), /// A map of rigid variables that we build up during a branch of type checking const FreeVar = struct { ident: base.Ident.Idx, var_: Var }; -/// A struct scratch info aout a static dispatch constaint +/// A struct scratch info about a static dispatch constraint const ScratchStaticDispatchConstraint = struct { var_: Var, constraint: types_mod.StaticDispatchConstraint, @@ -669,7 +669,7 @@ pub fn checkFile(self: *Self) std.mem.Allocator.Error!void { } // Check any accumulated static dispatch constraints - try self.checkDeferredStaticDispatchContraints(); + try self.checkDeferredStaticDispatchConstraints(); } // repl // @@ -703,7 +703,7 @@ pub fn checkExprRepl(self: *Self, expr_idx: CIR.Expr.Idx) std.mem.Allocator.Erro try self.generalizer.generalize(&self.var_pool, rank); // Check any accumulated static dispatch constraints - try self.checkDeferredStaticDispatchContraints(); + try self.checkDeferredStaticDispatchConstraints(); } // defs // @@ -727,9 +727,6 @@ fn checkDef(self: *Self, def_idx: CIR.Def.Idx) std.mem.Allocator.Error!void { // Initially set to be flex const placeholder_ptrn_var = ModuleEnv.varFrom(def.pattern); - var type_writer = try self.cir.initTypeWriter(); - defer type_writer.deinit(); - // Check the pattern // // Generate a fresh variable, because the original pattern has a placeholder @@ -780,9 +777,6 @@ fn generateStmtTypeDeclType( const decl = self.cir.store.getStatement(decl_idx); const decl_var = ModuleEnv.varFrom(decl_idx); - var type_writer = try self.cir.initTypeWriter(); - defer type_writer.deinit(); - switch (decl) { .s_alias_decl => |alias| { // Get the type header's args @@ -946,14 +940,14 @@ fn generateAnnotationType(self: *Self, annotation_idx: CIR.Annotation.Idx) std.m _ = try self.types.setVarRedirect(ModuleEnv.varFrom(annotation_idx), ModuleEnv.varFrom(annotation.anno)); } -/// Given a where clause, generate static dispatchs constraints and add to scratch_static_dispatch_constraints +/// Given a where clause, generate static dispatch constraints and add to scratch_static_dispatch_constraints fn generateStaticDispatchConstraintFromWhere(self: *Self, where_idx: CIR.WhereClause.Idx) std.mem.Allocator.Error!void { const where = self.cir.store.getWhereClause(where_idx); const where_region = self.cir.store.getNodeRegion(ModuleEnv.nodeIdxFrom(where_idx)); switch (where) { .w_method => |method| { - // Generate type of the thing dispatch reciever + // Generate type of the thing dispatch receiver try self.generateAnnoTypeInPlace(method.var_, .annotation); const method_var = ModuleEnv.varFrom(method.var_); @@ -2952,9 +2946,6 @@ fn checkExpr(self: *Self, expr_idx: CIR.Expr.Idx, rank: types_mod.Rank, expected .e_dot_access => |dot_access| { // Dot access can either indicate record access or static dispatch - var type_writer = try self.cir.initTypeWriter(); - defer type_writer.deinit(); - // Check the receiver expression // E.g. thing.val // ^^^^^ @@ -2975,7 +2966,7 @@ fn checkExpr(self: *Self, expr_idx: CIR.Expr.Idx, rank: types_mod.Rank, expected // For static dispatch to be used like `thing.dispatch(...)` the // method being dispatched on must accept the type of `thing` as - // it's first arg. So, we prepend the `reciever_var` to the args list + // it's first arg. So, we prepend the `receiver_var` to the args list const first_arg_range = try self.types.appendVars(&.{receiver_var}); const rest_args_range = try self.types.appendVars(@ptrCast(dispatch_arg_expr_idxs)); const dispatch_arg_vars_range = Var.SafeList.Range{ @@ -2997,13 +2988,13 @@ fn checkExpr(self: *Self, expr_idx: CIR.Expr.Idx, rank: types_mod.Rank, expected try self.var_pool.addVarToRank(constraint_fn_var, rank); // Then, create the static dispatch constraint - const contraint = StaticDispatchConstraint{ + const constraint = StaticDispatchConstraint{ .fn_name = dot_access.field_name, .fn_var = constraint_fn_var, }; - const constraint_range = try self.types.appendStaticDispatchConstraints(&.{contraint}); + const constraint_range = try self.types.appendStaticDispatchConstraints(&.{constraint}); - // Create our constrained flex, and unify it with the reciever + // Create our constrained flex, and unify it with the receiver const constrained_var = try self.freshFromContent( .{ .flex = Flex{ .name = null, .constraints = constraint_range } }, rank, @@ -3620,10 +3611,7 @@ fn copyVar(self: *Self, other_module_var: Var, other_module_env: *const ModuleEn /// /// Initially, we only have to check constraint for `Test.to_str2`. But when we /// process that, we then have to check `Test.to_str`. -fn checkDeferredStaticDispatchContraints(self: *Self) std.mem.Allocator.Error!void { - var type_writer = try self.cir.initTypeWriter(); - defer type_writer.deinit(); - +fn checkDeferredStaticDispatchConstraints(self: *Self) std.mem.Allocator.Error!void { var deferred_constraint_len = self.deferred_static_dispatch_constraints.items.items.len; var deferred_constraint_index: usize = 0; while (deferred_constraint_index < deferred_constraint_len) : ({ @@ -3706,7 +3694,7 @@ fn checkDeferredStaticDispatchContraints(self: *Self) std.mem.Allocator.Error!vo // Get the def index in the original env const node_idx_in_original_env = original_env.getExposedNodeIndexById(ident_in_original_env) orelse { - // This can happen if somehow, the orignal module has + // This can happen if somehow, the original module has // an ident that matches the method/type, but it doesn't // actually have/expose the method. This should be // impossible, but we handle it gracefully diff --git a/src/check/snapshot.zig b/src/check/snapshot.zig index 47c1feca26..ce92122646 100644 --- a/src/check/snapshot.zig +++ b/src/check/snapshot.zig @@ -18,7 +18,7 @@ const SnapshotContentList = collections.SafeList(SnapshotContent); const SnapshotContentIdxSafeList = collections.SafeList(SnapshotContentIdx); const SnapshotRecordFieldSafeList = collections.SafeMultiList(SnapshotRecordField); const SnapshotTagSafeList = collections.SafeMultiList(SnapshotTag); -const SnapshotStaticDispatchContraintSafeList = collections.SafeList(SnapshotStaticDispatchContraint); +const SnapshotStaticDispatchConstraintSafeList = collections.SafeList(SnapshotStaticDispatchConstraint); const MkSafeMultiList = collections.SafeMultiList; const Var = types.Var; @@ -49,13 +49,13 @@ pub const Store = struct { content_indexes: SnapshotContentIdxSafeList, record_fields: SnapshotRecordFieldSafeList, tags: SnapshotTagSafeList, - static_dispatch_constraints: SnapshotStaticDispatchContraintSafeList, + static_dispatch_constraints: SnapshotStaticDispatchConstraintSafeList, // Scratch scratch_content: base.Scratch(SnapshotContentIdx), scratch_tags: base.Scratch(SnapshotTag), scratch_record_fields: base.Scratch(SnapshotRecordField), - scratch_static_dispatch_constraints: base.Scratch(SnapshotStaticDispatchContraint), + scratch_static_dispatch_constraints: base.Scratch(SnapshotStaticDispatchConstraint), pub fn initCapacity(gpa: Allocator, capacity: usize) std.mem.Allocator.Error!Self { return .{ @@ -65,11 +65,11 @@ pub const Store = struct { .content_indexes = try SnapshotContentIdxSafeList.initCapacity(gpa, capacity), .record_fields = try SnapshotRecordFieldSafeList.initCapacity(gpa, 256), .tags = try SnapshotTagSafeList.initCapacity(gpa, 256), - .static_dispatch_constraints = try SnapshotStaticDispatchContraintSafeList.initCapacity(gpa, 64), + .static_dispatch_constraints = try SnapshotStaticDispatchConstraintSafeList.initCapacity(gpa, 64), .scratch_content = try base.Scratch(SnapshotContentIdx).init(gpa), .scratch_tags = try base.Scratch(SnapshotTag).init(gpa), .scratch_record_fields = try base.Scratch(SnapshotRecordField).init(gpa), - .scratch_static_dispatch_constraints = try base.Scratch(SnapshotStaticDispatchContraint).init(gpa), + .scratch_static_dispatch_constraints = try base.Scratch(SnapshotStaticDispatchConstraint).init(gpa), }; } @@ -412,7 +412,7 @@ pub const Store = struct { self: *Self, store: *const TypesStore, range: types.StaticDispatchConstraint.SafeList.Range, - ) std.mem.Allocator.Error!SnapshotStaticDispatchContraintSafeList.Range { + ) std.mem.Allocator.Error!SnapshotStaticDispatchConstraintSafeList.Range { const scratch_top = self.scratch_static_dispatch_constraints.top(); defer self.scratch_static_dispatch_constraints.clearFrom(scratch_top); @@ -427,8 +427,8 @@ pub const Store = struct { self: *Self, store: *const TypesStore, constraint: types.StaticDispatchConstraint, - ) std.mem.Allocator.Error!SnapshotStaticDispatchContraint { - return SnapshotStaticDispatchContraint{ + ) std.mem.Allocator.Error!SnapshotStaticDispatchConstraint { + return SnapshotStaticDispatchConstraint{ .fn_name = constraint.fn_name, .fn_content = try self.deepCopyVar(store, constraint.fn_var), }; @@ -443,7 +443,7 @@ pub const Store = struct { return self.record_fields.sliceRange(range); } - pub fn sliceStaticDispatchConstraints(self: *const Self, range: SnapshotStaticDispatchContraintSafeList.Range) SnapshotStaticDispatchContraintSafeList.Slice { + pub fn sliceStaticDispatchConstraints(self: *const Self, range: SnapshotStaticDispatchConstraintSafeList.Range) SnapshotStaticDispatchConstraintSafeList.Slice { return self.static_dispatch_constraints.sliceRange(range); } @@ -466,13 +466,13 @@ pub const SnapshotContent = union(enum) { pub const SnapshotFlex = struct { name: ?Ident.Idx, var_: Var, - constraints: SnapshotStaticDispatchContraintSafeList.Range, + constraints: SnapshotStaticDispatchConstraintSafeList.Range, }; /// TODO pub const SnapshotRigid = struct { name: Ident.Idx, - constraints: SnapshotStaticDispatchContraintSafeList.Range, + constraints: SnapshotStaticDispatchConstraintSafeList.Range, }; /// TODO @@ -558,7 +558,7 @@ pub const SnapshotTag = struct { }; /// TODO -pub const SnapshotStaticDispatchContraint = struct { +pub const SnapshotStaticDispatchConstraint = struct { fn_name: Ident.Idx, fn_content: SnapshotContentIdx, // Index into SnapshotStore.contents }; @@ -590,7 +590,7 @@ pub const SnapshotWriter = struct { name_counters: std.EnumMap(TypeContext, u32), flex_var_names_map: std.AutoHashMap(Var, FlexVarNameRange), flex_var_names: std.array_list.Managed(u8), - static_dispatch_constraints: std.array_list.Managed(SnapshotStaticDispatchContraint), + static_dispatch_constraints: std.array_list.Managed(SnapshotStaticDispatchConstraint), count_seen_idxs: std.array_list.Managed(SnapshotContentIdx), const FlexVarNameRange = struct { start: usize, end: usize }; @@ -607,7 +607,7 @@ pub const SnapshotWriter = struct { .name_counters = std.EnumMap(TypeContext, u32).init(.{}), .flex_var_names_map = std.AutoHashMap(Var, FlexVarNameRange).init(gpa), .flex_var_names = std.array_list.Managed(u8).init(gpa), - .static_dispatch_constraints = std.array_list.Managed(SnapshotStaticDispatchContraint).init(gpa), + .static_dispatch_constraints = std.array_list.Managed(SnapshotStaticDispatchConstraint).init(gpa), .count_seen_idxs = std.array_list.Managed(SnapshotContentIdx).init(gpa), }; } @@ -631,7 +631,7 @@ pub const SnapshotWriter = struct { .name_counters = std.EnumMap(TypeContext, u32).init(.{}), .flex_var_names_map = std.AutoHashMap(Var, FlexVarNameRange).init(gpa), .flex_var_names = std.array_list.Managed(u8).init(gpa), - .static_dispatch_constraints = std.array_list.Managed(SnapshotStaticDispatchContraint).init(gpa), + .static_dispatch_constraints = std.array_list.Managed(SnapshotStaticDispatchConstraint).init(gpa), .count_seen_idxs = try std.array_list.Managed(SnapshotContentIdx).init(gpa), }; } diff --git a/src/check/test/type_checking_integration.zig b/src/check/test/type_checking_integration.zig index 719cdc6a68..7166587b2f 100644 --- a/src/check/test/type_checking_integration.zig +++ b/src/check/test/type_checking_integration.zig @@ -1150,7 +1150,7 @@ const DefExpectation = union(enum) { /// A unified helper to run the full pipeline: parse, canonicalize, and type-check source code. /// /// Behavior depends on the expectation: -/// Pass: Asserts whole module type checks, and assert the speicifed def matches the expected type string +/// Pass: Asserts whole module type checks, and assert the specified def matches the expected type string /// Fail: Asserts that there is exactly 1 type error in the module and it's title matches the expected string fn checkTypesModule( comptime source_expr: []const u8, diff --git a/src/types/TypeWriter.zig b/src/types/TypeWriter.zig index 45cd5a8c5b..563bf057c4 100644 --- a/src/types/TypeWriter.zig +++ b/src/types/TypeWriter.zig @@ -55,7 +55,7 @@ types: *const TypesStore, idents: *const Ident.Store, buf: std.array_list.Managed(u8), seen: std.array_list.Managed(Var), -seen_count_var_occurences: std.array_list.Managed(Var), +seen_count_var_occurrences: std.array_list.Managed(Var), next_name_index: u32, name_counters: std.EnumMap(TypeContext, u32), flex_var_names_map: std.AutoHashMap(Var, FlexVarNameRange), @@ -71,7 +71,7 @@ pub fn initFromParts(gpa: std.mem.Allocator, types_store: *const TypesStore, ide .idents = idents, .buf = try std.array_list.Managed(u8).initCapacity(gpa, 32), .seen = try std.array_list.Managed(Var).initCapacity(gpa, 16), - .seen_count_var_occurences = try std.array_list.Managed(Var).initCapacity(gpa, 16), + .seen_count_var_occurrences = try std.array_list.Managed(Var).initCapacity(gpa, 16), .next_name_index = 0, .name_counters = std.EnumMap(TypeContext, u32).init(.{}), .flex_var_names_map = std.AutoHashMap(Var, FlexVarNameRange).init(gpa), @@ -84,7 +84,7 @@ pub fn initFromParts(gpa: std.mem.Allocator, types_store: *const TypesStore, ide pub fn deinit(self: *TypeWriter) void { self.buf.deinit(); self.seen.deinit(); - self.seen_count_var_occurences.deinit(); + self.seen_count_var_occurrences.deinit(); self.flex_var_names_map.deinit(); self.flex_var_names.deinit(); self.static_dispatch_constraints.deinit(); @@ -94,7 +94,7 @@ pub fn deinit(self: *TypeWriter) void { pub fn reset(self: *TypeWriter) void { self.buf.clearRetainingCapacity(); self.seen.clearRetainingCapacity(); - self.seen_count_var_occurences.clearRetainingCapacity(); + self.seen_count_var_occurrences.clearRetainingCapacity(); self.flex_var_names_map.clearRetainingCapacity(); self.flex_var_names.clearRetainingCapacity(); self.static_dispatch_constraints.clearRetainingCapacity(); @@ -821,7 +821,7 @@ pub fn writeFlexVarName(self: *TypeWriter, var_: Var, context: TypeContext, root /// Count how many times a variable appears in a type fn countVarOccurrences(self: *TypeWriter, search_var: Var, root_var: Var) std.mem.Allocator.Error!usize { - self.seen_count_var_occurences.clearRetainingCapacity(); + self.seen_count_var_occurrences.clearRetainingCapacity(); var count: usize = 0; try self.countVar(search_var, root_var, &count); @@ -847,13 +847,13 @@ fn countVar(self: *TypeWriter, search_var: Var, current_var: Var, count: *usize) // Check if we've already seen this var // This avoids infinite recursion - for (self.seen_count_var_occurences.items) |seen| { + for (self.seen_count_var_occurrences.items) |seen| { if (seen == resolved.var_) return; } // Record that we've seen this var - try self.seen_count_var_occurences.append(resolved.var_); - defer _ = self.seen_count_var_occurences.pop(); + try self.seen_count_var_occurrences.append(resolved.var_); + defer _ = self.seen_count_var_occurrences.pop(); // Then recurse switch (resolved.desc.content) { diff --git a/test/snapshots/static_dispatch/Adv.md b/test/snapshots/static_dispatch/Adv.md index f1b8ad2399..04fe8feaad 100644 --- a/test/snapshots/static_dispatch/Adv.md +++ b/test/snapshots/static_dispatch/Adv.md @@ -25,6 +25,17 @@ mismatch = { next_val } +mismatch2 = { + val = Adv.Val(10, "hello") + next_val = val.update_strr(100) + next_val +} + +mismatch3 = { + next_val = "Hello".update(100) + next_val +} + main : (Str, U64) main = { val = Adv.Val(10, "hello") @@ -34,6 +45,8 @@ main = { ~~~ # EXPECTED TYPE MISMATCH - Adv.md:17:13:17:32 +MISSING METHOD - Adv.md:23:13:23:33 +TYPE DOES NOT HAVE METHODS - Adv.md:28:13:28:32 # PROBLEMS **TYPE MISMATCH** This expression is used in an unexpected way: @@ -49,6 +62,27 @@ It has the type: But I expected it to be: _Adv, Str -> Adv_ +**MISSING METHOD** +The **Adv** type does not have a **update_strr** method: +**Adv.md:23:13:23:33:** +```roc + next_val = val.update_strr(100) +``` + ^^^^^^^^^^^^^^^^^^^^ + + +**Hint:** Did you forget to define **update_strr** in the type's method block? + +**TYPE DOES NOT HAVE METHODS** +You're trying to call the `update` method on a `Str`: +**Adv.md:28:13:28:32:** +```roc + next_val = "Hello".update(100) +``` + ^^^^^^^^^^^^^^^^^^^ + +But `Str` doesn't support methods. + # TOKENS ~~~zig UpperIdent,OpColonEqual,OpenSquare,UpperIdent,NoSpaceOpenRound,UpperIdent,Comma,UpperIdent,CloseRound,CloseSquare,Dot,OpenCurly, @@ -66,6 +100,15 @@ LowerIdent,OpAssign,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,Int,Comma,S LowerIdent,OpAssign,LowerIdent,NoSpaceDotLowerIdent,NoSpaceOpenRound,Int,CloseRound, LowerIdent, CloseCurly, +LowerIdent,OpAssign,OpenCurly, +LowerIdent,OpAssign,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,Int,Comma,StringStart,StringPart,StringEnd,CloseRound, +LowerIdent,OpAssign,LowerIdent,NoSpaceDotLowerIdent,NoSpaceOpenRound,Int,CloseRound, +LowerIdent, +CloseCurly, +LowerIdent,OpAssign,OpenCurly, +LowerIdent,OpAssign,StringStart,StringPart,StringEnd,NoSpaceDotLowerIdent,NoSpaceOpenRound,Int,CloseRound, +LowerIdent, +CloseCurly, LowerIdent,OpColon,OpenRound,UpperIdent,Comma,UpperIdent,CloseRound, LowerIdent,OpAssign,OpenCurly, LowerIdent,OpAssign,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,Int,Comma,StringStart,StringPart,StringEnd,CloseRound, @@ -166,6 +209,38 @@ EndOfFile, (e-ident (raw "update_str")) (e-int (raw "100"))))) (e-ident (raw "next_val"))))) + (s-decl + (p-ident (raw "mismatch2")) + (e-block + (statements + (s-decl + (p-ident (raw "val")) + (e-apply + (e-tag (raw "Adv.Val")) + (e-int (raw "10")) + (e-string + (e-string-part (raw "hello"))))) + (s-decl + (p-ident (raw "next_val")) + (e-field-access + (e-ident (raw "val")) + (e-apply + (e-ident (raw "update_strr")) + (e-int (raw "100"))))) + (e-ident (raw "next_val"))))) + (s-decl + (p-ident (raw "mismatch3")) + (e-block + (statements + (s-decl + (p-ident (raw "next_val")) + (e-field-access + (e-string + (e-string-part (raw "Hello"))) + (e-apply + (e-ident (raw "update")) + (e-int (raw "100"))))) + (e-ident (raw "next_val"))))) (s-type-anno (name "main") (ty-tuple (ty (name "Str")) @@ -221,6 +296,17 @@ mismatch = { next_val } +mismatch2 = { + val = Adv.Val(10, "hello") + next_val = val.update_strr(100) + next_val +} + +mismatch3 = { + next_val = "Hello".update(100) + next_val +} + main : (Str, U64) main = { val = Adv.Val(10, "hello") @@ -252,6 +338,40 @@ main = { (e-num (value "100"))))) (e-lookup-local (p-assign (ident "next_val"))))) + (d-let + (p-assign (ident "mismatch2")) + (e-block + (s-let + (p-assign (ident "val")) + (e-nominal (nominal "Adv") + (e-tag (name "Val") + (args + (e-num (value "10")) + (e-string + (e-literal (string "hello"))))))) + (s-let + (p-assign (ident "next_val")) + (e-dot-access (field "update_strr") + (receiver + (e-lookup-local + (p-assign (ident "val")))) + (args + (e-num (value "100"))))) + (e-lookup-local + (p-assign (ident "next_val"))))) + (d-let + (p-assign (ident "mismatch3")) + (e-block + (s-let + (p-assign (ident "next_val")) + (e-dot-access (field "update") + (receiver + (e-string + (e-literal (string "Hello")))) + (args + (e-num (value "100"))))) + (e-lookup-local + (p-assign (ident "next_val"))))) (d-let (p-assign (ident "main")) (e-block @@ -376,6 +496,8 @@ main = { ~~~clojure (inferred-types (defs + (patt (type "_a")) + (patt (type "_a")) (patt (type "_a")) (patt (type "(Str, Num(Int(Unsigned64)))")) (patt (type "Adv -> Str")) @@ -386,6 +508,8 @@ main = { (nominal (type "Adv") (ty-header (name "Adv")))) (expressions + (expr (type "_a")) + (expr (type "_a")) (expr (type "_a")) (expr (type "(Str, Num(Int(Unsigned64)))")) (expr (type "Adv -> Str"))