mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Typos + snapshot problems
This commit is contained in:
parent
d2fbc1c07c
commit
8ea4eaa488
7 changed files with 164 additions and 52 deletions
|
|
@ -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 = .{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue