Fix some nominal str things

This commit is contained in:
Richard Feldman 2025-11-16 23:27:48 -05:00
parent 129e1e1d28
commit dd765a820d
No known key found for this signature in database
23 changed files with 137 additions and 191 deletions

View file

@ -285,14 +285,6 @@ pub fn populateModuleEnvs(
.statement_idx = statement_idx,
});
}
// Also add an entry for "Builtin" module itself so that nominal types
// with origin_module="Builtin" can be looked up in module_envs
const builtin_module_ident = try calling_module_env.insertIdent(base.Ident.for_text("Builtin"));
try module_envs_map.put(builtin_module_ident, .{
.env = builtin_module_env,
.statement_idx = null, // No specific statement - this is the module itself
});
}
/// Set up auto-imported builtin types (Bool, Try, Dict, Set, Str, and numeric types) from the Builtin module.

View file

@ -4037,6 +4037,9 @@ fn handleRecursiveConstraint(
/// Initially, we only have to check constraint for `Test.to_str2`. But when we
/// process that, we then have to check `Test.to_str`.
fn checkDeferredStaticDispatchConstraints(self: *Self, env: *Env) std.mem.Allocator.Error!void {
// Cache the "Builtin" identifier from the current module for comparison
const builtin_ident = self.cir.common.findIdent("Builtin");
var deferred_constraint_len = env.deferred_static_dispatch_constraints.items.items.len;
var deferred_constraint_index: usize = 0;
while (deferred_constraint_index < deferred_constraint_len) : ({
@ -4129,10 +4132,6 @@ fn checkDeferredStaticDispatchConstraints(self: *Self, env: *Env) std.mem.Alloca
// If the root type is aa flex, then we there's nothing to check
continue;
} else if (dispatcher_content == .structure and dispatcher_content.structure == .nominal_type) {
// TODO: Internal types like Str, Try, List, etc are not
// technically nominal types. So in those cases, we should lookup
// the builtin module manually and dispatch that way
// If the root type is a nominal type, then this is valid static dispatch
const nominal_type = dispatcher_content.structure.nominal_type;
@ -4147,7 +4146,15 @@ fn checkDeferredStaticDispatchConstraints(self: *Self, env: *Env) std.mem.Alloca
if (is_this_module) {
break :blk self.cir;
} else {
// Get the module env from module_envs
// Check if this is the Builtin module - use the direct reference
// Internal types like Str, Try, List, etc have methods defined in Builtin
if (builtin_ident != null and original_module_ident == builtin_ident.?) {
if (self.common_idents.builtin_module) |builtin_env| {
break :blk builtin_env;
}
}
// Get the module env from module_envs for user-defined modules
std.debug.assert(self.module_envs != null);
const module_envs = self.module_envs.?;
const mb_original_module_env = module_envs.get(original_module_ident);

View file

@ -281,7 +281,12 @@ pub const Interpreter = struct {
.imported_modules = std.StringHashMap(*const can.ModuleEnv).init(allocator),
.def_stack = try std.array_list.Managed(DefInProgress).initCapacity(allocator, 4),
};
result.runtime_layout_store = try layout.Store.init(env, result.runtime_types);
// Get the "Builtin.Str" identifier from the runtime module's identifier store
// (identifiers are per-module, so we need to insert "Builtin.Str" into the runtime module's table)
const builtin_str_ident = env.common.findIdent("Builtin.Str");
result.runtime_layout_store = try layout.Store.init(env, result.runtime_types, builtin_str_ident);
return result;
}

View file

@ -61,6 +61,10 @@ pub const Store = struct {
// Reusable work stack for addTypeVar (so it can be stack-safe instead of recursing)
work: work.Work,
// Identifier for "Builtin.Str" to recognize the string type without string comparisons
// (null when compiling Builtin module itself or when Builtin.Str isn't available)
builtin_str_ident: ?Ident.Idx,
// Number of primitive types that are pre-populated in the layout store
// Must be kept in sync with the sentinel values in layout.zig Idx enum
const num_scalars = 16;
@ -105,6 +109,7 @@ pub const Store = struct {
pub fn init(
env: *ModuleEnv,
type_store: *const types_store.Store,
builtin_str_ident: ?Ident.Idx,
) std.mem.Allocator.Error!Self {
// Get the number of variables from the type store's slots
const capacity = type_store.slots.backing.len();
@ -144,6 +149,7 @@ pub const Store = struct {
.tuple_data = try collections.SafeList(TupleData).initCapacity(env.gpa, 256),
.layouts_by_var = layouts_by_var,
.work = try Work.initCapacity(env.gpa, 32),
.builtin_str_ident = builtin_str_ident,
};
}
@ -886,11 +892,13 @@ pub const Store = struct {
},
.nominal_type => |nominal_type| {
// Special-case Builtin.Str: it has a tag union backing type, but
// should have RocStr layout (3 pointers)
const str_ident = self.env.common.findIdent("Builtin.Str");
if (str_ident != null and nominal_type.ident.ident_idx == str_ident.?) {
// Str nominal type should use the string layout
break :flat_type Layout.str();
// should have RocStr layout (3 pointers).
// Check if this nominal type's identifier matches "Builtin.Str"
if (self.builtin_str_ident) |builtin_str| {
if (nominal_type.ident.ident_idx == builtin_str) {
// This is Builtin.Str - use string layout
break :flat_type Layout.str();
}
}
// TODO special-case the builtin Num type here.

View file

@ -39,7 +39,7 @@ test "addTypeVar - bool type" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();
@ -57,7 +57,7 @@ test "addTypeVar - default layouts for polymorphic types" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();
@ -91,7 +91,7 @@ test "addTypeVar - host opaque types compile to opaque_ptr" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();
@ -122,7 +122,7 @@ test "addTypeVar - zero-sized types (ZST)" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();
@ -148,7 +148,7 @@ test "addTypeVar - record with dropped zero-sized fields" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();
@ -175,7 +175,7 @@ test "addTypeVar - record with only zero-sized fields errors" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();
@ -200,7 +200,7 @@ test "record field sorting by alignment then name" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();
@ -235,7 +235,7 @@ test "record size and alignment calculation" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();
@ -271,7 +271,7 @@ test "record with chained extensions" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();
@ -308,7 +308,7 @@ test "record extension with non-record type fails" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();
@ -325,7 +325,7 @@ test "deeply nested containers with inner ZST" {
lt.gpa = testing.allocator;
lt.module_env = try ModuleEnv.init(lt.gpa, "");
lt.type_store = try types_store.Store.init(lt.gpa);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store);
lt.layout_store = try Store.init(&lt.module_env, &lt.type_store, null);
lt.type_scope = TypeScope.init(lt.gpa);
defer lt.deinit();

View file

@ -42,6 +42,7 @@ main = {
# EXPECTED
MODULE NOT FOUND - can_import_comprehensive.md:1:1:1:17
MODULE NOT FOUND - can_import_comprehensive.md:2:1:2:48
DUPLICATE DEFINITION - can_import_comprehensive.md:3:1:3:27
MODULE NOT FOUND - can_import_comprehensive.md:3:1:3:27
UNDEFINED VARIABLE - can_import_comprehensive.md:6:14:6:22
UNDEFINED VARIABLE - can_import_comprehensive.md:7:14:7:23
@ -74,6 +75,24 @@ import http.Client as Http exposing [get, post]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**DUPLICATE DEFINITION**
The name `Str` is being redeclared in this scope.
The redeclaration is here:
**can_import_comprehensive.md:3:1:3:27:**
```roc
import utils.String as Str
```
^^^^^^^^^^^^^^^^^^^^^^^^^^
But `Str` was already defined here:
**can_import_comprehensive.md:1:1:1:1:**
```roc
import json.Json
```
^
**MODULE NOT FOUND**
The module `utils.String` was not found in this Roc project.

View file

@ -311,9 +311,6 @@ processData : Config, List(Value) -> Try(List(Value), Error)
**DOES NOT EXIST**
`List.mapTry` does not exist.
`List` is in scope, but it has no associated `mapTry`.
It's referenced here:
**can_import_exposing_types.md:22:5:22:16:**
```roc
List.mapTry(
@ -801,7 +798,7 @@ combineTrys = |jsonTry, httpStatus|
(p-assign (ident "config"))
(p-assign (ident "values")))
(e-call
(e-runtime-error (tag "nested_value_not_found"))
(e-runtime-error (tag "qualified_ident_does_not_exist"))
(e-lookup-local
(p-assign (ident "values")))
(e-closure

View file

@ -899,7 +899,7 @@ The fourth pattern has this type:
_Str_
But all the previous patterns have this type:
_[Blue]_others_
_[Blue][ProvidedByCompiler]_
All patterns in an `match` must have compatible types.
@ -929,7 +929,7 @@ It has the type:
__arg -> _ret_
But I expected it to be:
_[Blue]_others, [Tb]_others2 -> Error_
_[Blue][ProvidedByCompiler], [Tb]_others -> Error_
**UNUSED VALUE**
This expression produces a value, but it's not being used:
@ -2001,7 +2001,7 @@ expect {
(patt (type "Bool -> Num(_size)"))
(patt (type "Error"))
(patt (type "Bool -> Error"))
(patt (type "[Blue]_others, [Tb]_others2 -> Error"))
(patt (type "[Blue][ProvidedByCompiler], [Tb]_others -> Error"))
(patt (type "Error"))
(patt (type "_arg -> [Stdo!(Error)]_others"))
(patt (type "{ }"))
@ -2038,7 +2038,7 @@ expect {
(expr (type "Bool -> Num(_size)"))
(expr (type "Error"))
(expr (type "Bool -> Error"))
(expr (type "[Blue]_others, [Tb]_others2 -> Error"))
(expr (type "[Blue][ProvidedByCompiler], [Tb]_others -> Error"))
(expr (type "Error"))
(expr (type "_arg -> [Stdo!(Error)]_others"))
(expr (type "{ }"))

View file

@ -909,7 +909,7 @@ The fourth pattern has this type:
_Str_
But all the previous patterns have this type:
_[Blue]_others_
_[Blue][ProvidedByCompiler]_
All patterns in an `match` must have compatible types.
@ -1980,7 +1980,7 @@ expect {
(patt (type "Bool -> Num(_size)"))
(patt (type "Error"))
(patt (type "[Rum]_others -> Error"))
(patt (type "[Blue]_others -> Error"))
(patt (type "[Blue][ProvidedByCompiler] -> Error"))
(patt (type "Error"))
(patt (type "_arg -> [Stdo!(Error)]_others"))
(patt (type "{ }"))
@ -2017,7 +2017,7 @@ expect {
(expr (type "Bool -> Num(_size)"))
(expr (type "Error"))
(expr (type "[Rum]_others -> Error"))
(expr (type "[Blue]_others -> Error"))
(expr (type "[Blue][ProvidedByCompiler] -> Error"))
(expr (type "Error"))
(expr (type "_arg -> [Stdo!(Error)]_others"))
(expr (type "{ }"))

View file

@ -985,7 +985,7 @@ The fourth pattern has this type:
_Str_
But all the previous patterns have this type:
_[Red][Blue, Green]_others_
_[Red][Blue, Green][ProvidedByCompiler]_
All patterns in an `match` must have compatible types.
@ -1015,7 +1015,7 @@ It has the type:
__arg -> _ret_
But I expected it to be:
_[Red][Blue, Green]_others, _arg -> Error_
_[Red][Blue, Green][ProvidedByCompiler], _arg -> Error_
**UNUSED VALUE**
This expression produces a value, but it's not being used:
@ -2574,7 +2574,7 @@ expect {
(defs
(patt (type "Bool -> Num(_size)"))
(patt (type "Error -> Num(Int(Unsigned64))"))
(patt (type "[Red][Blue, Green]_others, _arg -> Error"))
(patt (type "[Red][Blue, Green][ProvidedByCompiler], _arg -> Error"))
(patt (type "Error"))
(patt (type "List(Error) -> Error"))
(patt (type "{}"))
@ -2621,7 +2621,7 @@ expect {
(expressions
(expr (type "Bool -> Num(_size)"))
(expr (type "Error -> Num(Int(Unsigned64))"))
(expr (type "[Red][Blue, Green]_others, _arg -> Error"))
(expr (type "[Red][Blue, Green][ProvidedByCompiler], _arg -> Error"))
(expr (type "Error"))
(expr (type "List(Error) -> Error"))
(expr (type "{}"))

View file

@ -905,7 +905,7 @@ The third pattern has this type:
_Str_
But all the previous patterns have this type:
_[Red, Blue]_others_
_[Red, Blue][ProvidedByCompiler]_
All patterns in an `match` must have compatible types.
@ -935,7 +935,7 @@ It has the type:
__arg -> _ret_
But I expected it to be:
_[Red, Blue]_others, _arg -> Error_
_[Red, Blue][ProvidedByCompiler], _arg -> Error_
**UNUSED VALUE**
This expression produces a value, but it's not being used:
@ -2252,7 +2252,7 @@ expect {
(patt (type "(Error, Error)"))
(patt (type "Bool -> Num(_size)"))
(patt (type "Error -> Num(Int(Unsigned64))"))
(patt (type "[Red, Blue]_others, _arg -> Error"))
(patt (type "[Red, Blue][ProvidedByCompiler], _arg -> Error"))
(patt (type "List(Error) -> Error"))
(patt (type "{}"))
(patt (type "Error")))
@ -2289,7 +2289,7 @@ expect {
(expr (type "(Error, Error)"))
(expr (type "Bool -> Num(_size)"))
(expr (type "Error -> Num(Int(Unsigned64))"))
(expr (type "[Red, Blue]_others, _arg -> Error"))
(expr (type "[Red, Blue][ProvidedByCompiler], _arg -> Error"))
(expr (type "List(Error) -> Error"))
(expr (type "{}"))
(expr (type "Error"))))

View file

@ -44,7 +44,7 @@ The `else` branch has the type:
_Str_
But the `then` branch has the type:
_[A]_others_
_[A][ProvidedByCompiler]_
All branches in an `if` must have compatible types.

View file

@ -14,22 +14,20 @@ wrong_type_function : I64 -> I64
wrong_type_function = |x| x * 3.14
~~~
# EXPECTED
TYPE MISMATCH - lambda_annotation_mismatch_error.md:3:27:3:29
MISSING METHOD - lambda_annotation_mismatch_error.md:3:23:3:29
+ - :0:0:0:0
TYPE MISMATCH - lambda_annotation_mismatch_error.md:7:31:7:35
# PROBLEMS
**TYPE MISMATCH**
This expression is used in an unexpected way:
**lambda_annotation_mismatch_error.md:3:27:3:29:**
**MISSING METHOD**
The value before this **+** operator has the type **Str**, which has no **plus** method:
**lambda_annotation_mismatch_error.md:3:23:3:29:**
```roc
string_function = |x| x + 42
```
^^
^^^^^^
It has the type:
_Num(_size)_
But the type annotation says it should have the type:
_Str_
**Hint: **The **+** operator calls a method named **plus** on the value preceding it, passing the value after the operator as the one argument.
**TYPE MISMATCH**
This expression is used in an unexpected way:
@ -123,9 +121,9 @@ NO CHANGE
~~~clojure
(inferred-types
(defs
(patt (type "Error -> Error"))
(patt (type "Str -> Error"))
(patt (type "Error -> Error")))
(expressions
(expr (type "Error -> Error"))
(expr (type "Str -> Error"))
(expr (type "Error -> Error"))))
~~~

View file

@ -45,9 +45,6 @@ PARSE ERROR - let_polymorphism_lists.md:14:32:14:45
UNRECOGNIZED SYNTAX - let_polymorphism_lists.md:12:16:12:27
UNRECOGNIZED SYNTAX - let_polymorphism_lists.md:13:16:13:27
UNRECOGNIZED SYNTAX - let_polymorphism_lists.md:14:18:14:31
DOES NOT EXIST - let_polymorphism_lists.md:25:12:25:20
DOES NOT EXIST - let_polymorphism_lists.md:26:12:26:20
DOES NOT EXIST - let_polymorphism_lists.md:27:12:27:20
# PROBLEMS
**UNEXPECTED TOKEN IN EXPRESSION**
The token **+** is not expected in an expression.
@ -148,45 +145,6 @@ all_float_list = float_list ++ my_empty_list
This might be a syntax error, an unsupported language feature, or a typo.
**DOES NOT EXIST**
`List.len` does not exist.
`List` is in scope, but it has no associated `len`.
It's referenced here:
**let_polymorphism_lists.md:25:12:25:20:**
```roc
len1 = List.len(all_int_list)
```
^^^^^^^^
**DOES NOT EXIST**
`List.len` does not exist.
`List` is in scope, but it has no associated `len`.
It's referenced here:
**let_polymorphism_lists.md:26:12:26:20:**
```roc
len2 = List.len(all_str_list)
```
^^^^^^^^
**DOES NOT EXIST**
`List.len` does not exist.
`List` is in scope, but it has no associated `len`.
It's referenced here:
**let_polymorphism_lists.md:27:12:27:20:**
```roc
len3 = List.len(all_float_list)
```
^^^^^^^^
# TOKENS
~~~zig
KwApp,OpenSquare,LowerIdent,CloseSquare,OpenCurly,LowerIdent,OpColon,KwPlatform,StringStart,StringPart,StringEnd,CloseCurly,
@ -413,19 +371,22 @@ main = |_| {
(s-let
(p-assign (ident "len1"))
(e-call
(e-runtime-error (tag "nested_value_not_found"))
(e-lookup-external
(builtin))
(e-lookup-local
(p-assign (ident "all_int_list")))))
(s-let
(p-assign (ident "len2"))
(e-call
(e-runtime-error (tag "nested_value_not_found"))
(e-lookup-external
(builtin))
(e-lookup-local
(p-assign (ident "all_str_list")))))
(s-let
(p-assign (ident "len3"))
(e-call
(e-runtime-error (tag "nested_value_not_found"))
(e-lookup-external
(builtin))
(e-lookup-local
(p-assign (ident "all_float_list")))))
(e-binop (op "add")

View file

@ -19,7 +19,6 @@ UNDEFINED VARIABLE - complex_list_tags.md:1:7:1:13
DOES NOT EXIST - complex_list_tags.md:3:42:3:51
DOES NOT EXIST - complex_list_tags.md:3:59:3:68
DOES NOT EXIST - complex_list_tags.md:4:59:4:68
DOES NOT EXIST - complex_list_tags.md:4:69:4:77
DOES NOT EXIST - complex_list_tags.md:5:62:5:71
DOES NOT EXIST - complex_list_tags.md:5:79:5:88
DOES NOT EXIST - complex_list_tags.md:5:101:5:110
@ -71,19 +70,6 @@ match events {
^^^^^^^^^
**DOES NOT EXIST**
`List.len` does not exist.
`List` is in scope, but it has no associated `len`.
It's referenced here:
**complex_list_tags.md:4:69:4:77:**
```roc
[KeyPress(key), .. as rest] => "key ${key} pressed, ${Num.toStr(List.len(rest))} more events"
```
^^^^^^^^
**DOES NOT EXIST**
`Num.toStr` does not exist.
@ -345,7 +331,8 @@ match events {
(e-call
(e-runtime-error (tag "qualified_ident_does_not_exist"))
(e-call
(e-runtime-error (tag "nested_value_not_found"))
(e-lookup-external
(builtin))
(e-lookup-local
(p-assign (ident "rest")))))
(e-literal (string " more events")))))

View file

@ -14,7 +14,6 @@ match data {
~~~
# EXPECTED
UNDEFINED VARIABLE - nested_patterns.md:1:7:1:11
DOES NOT EXIST - nested_patterns.md:2:57:2:65
# PROBLEMS
**UNDEFINED VARIABLE**
Nothing is named `data` in this scope.
@ -27,19 +26,6 @@ match data {
^^^^
**DOES NOT EXIST**
`List.len` does not exist.
`List` is in scope, but it has no associated `len`.
It's referenced here:
**nested_patterns.md:2:57:2:65:**
```roc
Container({ items: [First(x), .. as rest] }) => x + List.len(rest)
```
^^^^^^^^
# TOKENS
~~~zig
KwMatch,LowerIdent,OpenCurly,
@ -114,7 +100,8 @@ match data {
(e-lookup-local
(p-assign (ident "x")))
(e-call
(e-runtime-error (tag "nested_value_not_found"))
(e-lookup-external
(builtin))
(e-lookup-local
(p-assign (ident "rest")))))))
(branch
@ -143,5 +130,5 @@ match data {
~~~
# TYPES
~~~clojure
(expr (type "Error"))
(expr (type "Num(Int(Unsigned64))"))
~~~

View file

@ -89,7 +89,7 @@ DOES NOT EXIST - Color.md:51:75:51:85
DOES NOT EXIST - Color.md:51:93:51:103
DOES NOT EXIST - Color.md:68:14:68:27
TYPE DOES NOT HAVE METHODS - Color.md:22:15:22:26
TYPE DOES NOT HAVE METHODS - Color.md:29:13:29:26
MISSING METHOD - Color.md:29:13:29:26
TYPE DOES NOT HAVE METHODS - Color.md:35:17:35:41
TYPE DOES NOT HAVE METHODS - Color.md:36:21:36:45
TYPE DOES NOT HAVE METHODS - Color.md:37:21:37:45
@ -97,7 +97,7 @@ TYPE DOES NOT HAVE METHODS - Color.md:38:21:38:45
TYPE DOES NOT HAVE METHODS - Color.md:39:21:39:45
TYPE DOES NOT HAVE METHODS - Color.md:40:21:40:45
TYPE MISMATCH - Color.md:32:5:45:6
TYPE DOES NOT HAVE METHODS - Color.md:62:8:62:28
MISSING METHOD - Color.md:62:8:62:28
# PROBLEMS
**MODULE HEADER DEPRECATED**
The `module` header is deprecated.
@ -223,18 +223,16 @@ This type doesn't support methods:
**TYPE DOES NOT HAVE METHODS**
You're calling the method `to_utf8` on a type that doesn't support methods:
**MISSING METHOD**
This **to_utf8** method is being called on the type **Str**, which has no method with that name:
**Color.md:29:13:29:26:**
```roc
bytes = str.to_utf8()
```
^^^^^^^^^^^^^
This type doesn't support methods:
_Str_
**Hint: **For this to work, the type would need to have a method named **to_utf8** associated with it in the type's declaration.
**TYPE DOES NOT HAVE METHODS**
You're calling the method `is_char_in_hex_range` on a type that doesn't support methods:
@ -340,18 +338,16 @@ It has the type:
But the type annotation says it should have the type:
_Try(Color, [InvalidHex(Str)])_
**TYPE DOES NOT HAVE METHODS**
You're calling the method `is_named_color` on a type that doesn't support methods:
**MISSING METHOD**
This **is_named_color** method is being called on the type **Str**, which has no method with that name:
**Color.md:62:8:62:28:**
```roc
if str.is_named_color()
```
^^^^^^^^^^^^^^^^^^^^
This type doesn't support methods:
_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.
# TOKENS
~~~zig

View file

@ -8,21 +8,9 @@ type=expr
List.map
~~~
# EXPECTED
DOES NOT EXIST - simple_external_lookup.md:1:1:1:9
NIL
# PROBLEMS
**DOES NOT EXIST**
`List.map` does not exist.
`List` is in scope, but it has no associated `map`.
It's referenced here:
**simple_external_lookup.md:1:1:1:9:**
```roc
List.map
```
^^^^^^^^
NIL
# TOKENS
~~~zig
UpperIdent,NoSpaceDotLowerIdent,
@ -38,9 +26,10 @@ NO CHANGE
~~~
# CANONICALIZE
~~~clojure
(e-runtime-error (tag "nested_value_not_found"))
(e-lookup-external
(builtin))
~~~
# TYPES
~~~clojure
(expr (type "Error"))
(expr (type "List(a), (a -> b) -> List(b)"))
~~~

View file

@ -34,7 +34,7 @@ The `else` branch has the type:
_Str_
But the `then` branch has the type:
_[Err([TooBig]_others)]_others2_
_[Err([TooBig]_others)][ProvidedByCompiler]_
All branches in an `if` must have compatible types.

View file

@ -46,7 +46,7 @@ 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
MISSING METHOD - Adv.md:28:13:28:32
# PROBLEMS
**TYPE MISMATCH**
This expression is used in an unexpected way:
@ -73,18 +73,16 @@ This **update_strr** method is being called on the type **Adv**, which has no me
**Hint: **For this to work, the type would need to have a method named **update_strr** associated with it in the type's declaration.
**TYPE DOES NOT HAVE METHODS**
You're calling the method `update` on a type that doesn't support methods:
**MISSING METHOD**
This **update** method is being called on the type **Str**, which has no method with that name:
**Adv.md:28:13:28:32:**
```roc
next_val = "Hello".update(100)
```
^^^^^^^^^^^^^^^^^^^
This type doesn't support methods:
_Str_
**Hint: **For this to work, the type would need to have a method named **update** associated with it in the type's declaration.
# TOKENS
~~~zig

View file

@ -876,7 +876,7 @@ The fourth pattern has this type:
_Str_
But all the previous patterns have this type:
_[Red][Blue, Green]_others_
_[Red][Blue, Green][ProvidedByCompiler]_
All patterns in an `match` must have compatible types.
@ -906,7 +906,7 @@ It has the type:
__arg -> _ret_
But I expected it to be:
_[Red][Blue, Green]_others, _arg -> Error_
_[Red][Blue, Green][ProvidedByCompiler], _arg -> Error_
**UNUSED VALUE**
This expression produces a value, but it's not being used:
@ -2460,7 +2460,7 @@ expect {
(defs
(patt (type "Bool -> Num(_size)"))
(patt (type "Error -> Num(Int(Unsigned64))"))
(patt (type "[Red][Blue, Green]_others, _arg -> Error"))
(patt (type "[Red][Blue, Green][ProvidedByCompiler], _arg -> Error"))
(patt (type "List(Error) -> Error"))
(patt (type "{}"))
(patt (type "Error")))
@ -2506,7 +2506,7 @@ expect {
(expressions
(expr (type "Bool -> Num(_size)"))
(expr (type "Error -> Num(Int(Unsigned64))"))
(expr (type "[Red][Blue, Green]_others, _arg -> Error"))
(expr (type "[Red][Blue, Green][ProvidedByCompiler], _arg -> Error"))
(expr (type "List(Error) -> Error"))
(expr (type "{}"))
(expr (type "Error"))))

View file

@ -24,9 +24,9 @@ main! = |_| {}
~~~
# EXPECTED
UNEXPECTED TOKEN IN EXPRESSION - type_var_namespace.md:11:31:11:33
DOES NOT EXIST - type_var_namespace.md:11:14:11:24
UNRECOGNIZED SYNTAX - type_var_namespace.md:11:31:11:33
DOES NOT EXIST - type_var_namespace.md:11:34:11:49
TYPE MISMATCH - type_var_namespace.md:11:14:11:30
# PROBLEMS
**UNEXPECTED TOKEN IN EXPRESSION**
The token **|>** is not expected in an expression.
@ -39,19 +39,6 @@ Expressions can be identifiers, literals, function calls, or operators.
^^
**DOES NOT EXIST**
`List.first` does not exist.
`List` is in scope, but it has no associated `first`.
It's referenced here:
**type_var_namespace.md:11:14:11:24:**
```roc
result = List.first(list) |> Try.withDefault(elem)
```
^^^^^^^^^^
**UNRECOGNIZED SYNTAX**
I don't recognize this syntax.
@ -73,6 +60,20 @@ This might be a syntax error, an unsupported language feature, or a typo.
^^^^^^^^^^^^^^^
**TYPE MISMATCH**
This expression is used in an unexpected way:
**type_var_namespace.md:11:14:11:30:**
```roc
result = List.first(list) |> Try.withDefault(elem)
```
^^^^^^^^^^^^^^^^
It has the type:
_Try(elem, [ListWasEmpty])_
But the type annotation says it should have the type:
_elem_
# TOKENS
~~~zig
KwApp,OpenSquare,LowerIdent,CloseSquare,OpenCurly,LowerIdent,OpColon,KwPlatform,StringStart,StringPart,StringEnd,CloseCurly,
@ -171,7 +172,8 @@ main! = |_| {}
(s-let
(p-assign (ident "result"))
(e-call
(e-runtime-error (tag "nested_value_not_found"))
(e-lookup-external
(builtin))
(e-lookup-local
(p-assign (ident "list")))))
(s-expr