diff --git a/src/canonicalize/Can.zig b/src/canonicalize/Can.zig index 3aea89adf5..c1a2c71365 100644 --- a/src/canonicalize/Can.zig +++ b/src/canonicalize/Can.zig @@ -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. diff --git a/src/check/Check.zig b/src/check/Check.zig index 7e873dc3ae..c2bd31cb56 100644 --- a/src/check/Check.zig +++ b/src/check/Check.zig @@ -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); diff --git a/src/eval/interpreter.zig b/src/eval/interpreter.zig index 88c6b9ce69..5dbd1281d6 100644 --- a/src/eval/interpreter.zig +++ b/src/eval/interpreter.zig @@ -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; } diff --git a/src/layout/store.zig b/src/layout/store.zig index c97ddf5897..f2bbd2c4a6 100644 --- a/src/layout/store.zig +++ b/src/layout/store.zig @@ -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. diff --git a/src/layout/store_test.zig b/src/layout/store_test.zig index bfb2b265f9..e50b47ec27 100644 --- a/src/layout/store_test.zig +++ b/src/layout/store_test.zig @@ -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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.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(<.module_env, <.type_store); + lt.layout_store = try Store.init(<.module_env, <.type_store, null); lt.type_scope = TypeScope.init(lt.gpa); defer lt.deinit(); diff --git a/test/snapshots/can_import_comprehensive.md b/test/snapshots/can_import_comprehensive.md index a23fbebae7..c8b914a426 100644 --- a/test/snapshots/can_import_comprehensive.md +++ b/test/snapshots/can_import_comprehensive.md @@ -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. diff --git a/test/snapshots/can_import_exposing_types.md b/test/snapshots/can_import_exposing_types.md index 7d681fc7ab..83cb468eeb 100644 --- a/test/snapshots/can_import_exposing_types.md +++ b/test/snapshots/can_import_exposing_types.md @@ -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 diff --git a/test/snapshots/fuzz_crash/fuzz_crash_019.md b/test/snapshots/fuzz_crash/fuzz_crash_019.md index 68c20357ea..7457589d6a 100644 --- a/test/snapshots/fuzz_crash/fuzz_crash_019.md +++ b/test/snapshots/fuzz_crash/fuzz_crash_019.md @@ -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 "{ }")) diff --git a/test/snapshots/fuzz_crash/fuzz_crash_020.md b/test/snapshots/fuzz_crash/fuzz_crash_020.md index 962b6fa863..eae3a64f73 100644 --- a/test/snapshots/fuzz_crash/fuzz_crash_020.md +++ b/test/snapshots/fuzz_crash/fuzz_crash_020.md @@ -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 "{ }")) diff --git a/test/snapshots/fuzz_crash/fuzz_crash_023.md b/test/snapshots/fuzz_crash/fuzz_crash_023.md index 417e9d7557..9d7c8f0172 100644 --- a/test/snapshots/fuzz_crash/fuzz_crash_023.md +++ b/test/snapshots/fuzz_crash/fuzz_crash_023.md @@ -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 "{}")) diff --git a/test/snapshots/fuzz_crash/fuzz_crash_027.md b/test/snapshots/fuzz_crash/fuzz_crash_027.md index f3dcd44752..14abbdeeba 100644 --- a/test/snapshots/fuzz_crash/fuzz_crash_027.md +++ b/test/snapshots/fuzz_crash/fuzz_crash_027.md @@ -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")))) diff --git a/test/snapshots/fuzz_crash/fuzz_crash_028.md b/test/snapshots/fuzz_crash/fuzz_crash_028.md index 0a4eac484b..7d9c84c8c9 100644 Binary files a/test/snapshots/fuzz_crash/fuzz_crash_028.md and b/test/snapshots/fuzz_crash/fuzz_crash_028.md differ diff --git a/test/snapshots/if_then_else/if_then_else_simple_file.md b/test/snapshots/if_then_else/if_then_else_simple_file.md index b0bb2dc1f8..e5e45992ed 100644 --- a/test/snapshots/if_then_else/if_then_else_simple_file.md +++ b/test/snapshots/if_then_else/if_then_else_simple_file.md @@ -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. diff --git a/test/snapshots/lambda_annotation_mismatch_error.md b/test/snapshots/lambda_annotation_mismatch_error.md index ab3b5b27f5..2d1b1b490f 100644 --- a/test/snapshots/lambda_annotation_mismatch_error.md +++ b/test/snapshots/lambda_annotation_mismatch_error.md @@ -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")))) ~~~ diff --git a/test/snapshots/let_polymorphism_lists.md b/test/snapshots/let_polymorphism_lists.md index 7ad4f6c622..29020c907e 100644 --- a/test/snapshots/let_polymorphism_lists.md +++ b/test/snapshots/let_polymorphism_lists.md @@ -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") diff --git a/test/snapshots/match_expr/complex_list_tags.md b/test/snapshots/match_expr/complex_list_tags.md index 90a7a03fd3..8b65d3bbd6 100644 --- a/test/snapshots/match_expr/complex_list_tags.md +++ b/test/snapshots/match_expr/complex_list_tags.md @@ -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"))))) diff --git a/test/snapshots/match_expr/nested_patterns.md b/test/snapshots/match_expr/nested_patterns.md index df48208e59..558a73d152 100644 --- a/test/snapshots/match_expr/nested_patterns.md +++ b/test/snapshots/match_expr/nested_patterns.md @@ -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))")) ~~~ diff --git a/test/snapshots/plume_package/Color.md b/test/snapshots/plume_package/Color.md index 58554dda70..b7f0754c1b 100644 --- a/test/snapshots/plume_package/Color.md +++ b/test/snapshots/plume_package/Color.md @@ -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 diff --git a/test/snapshots/simple_external_lookup.md b/test/snapshots/simple_external_lookup.md index 1672681a7d..83d2c573e3 100644 --- a/test/snapshots/simple_external_lookup.md +++ b/test/snapshots/simple_external_lookup.md @@ -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)")) ~~~ diff --git a/test/snapshots/statement/return_stmt_block_example.md b/test/snapshots/statement/return_stmt_block_example.md index b74932916a..e4a005f424 100644 --- a/test/snapshots/statement/return_stmt_block_example.md +++ b/test/snapshots/statement/return_stmt_block_example.md @@ -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. diff --git a/test/snapshots/static_dispatch/Adv.md b/test/snapshots/static_dispatch/Adv.md index 7ecc8629d5..d7140332e2 100644 --- a/test/snapshots/static_dispatch/Adv.md +++ b/test/snapshots/static_dispatch/Adv.md @@ -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 diff --git a/test/snapshots/syntax_grab_bag.md b/test/snapshots/syntax_grab_bag.md index f92a8eedf1..dbf8a7804a 100644 --- a/test/snapshots/syntax_grab_bag.md +++ b/test/snapshots/syntax_grab_bag.md @@ -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")))) diff --git a/test/snapshots/type_var_namespace.md b/test/snapshots/type_var_namespace.md index a1c062735d..28322ed392 100644 --- a/test/snapshots/type_var_namespace.md +++ b/test/snapshots/type_var_namespace.md @@ -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