From 0df54f478fe4e10ef98fbcd190098841e33758ef Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Tue, 21 Oct 2025 18:58:46 -0400 Subject: [PATCH] Add support for `import foo.Bar.Baz` --- src/canonicalize/Can.zig | 73 ++-- src/canonicalize/test/node_store_test.zig | 8 + src/parse/AST.zig | 3 + src/parse/NodeStore.zig | 1 + src/parse/Parser.zig | 99 +++-- src/parse/test/ast_node_store_test.zig | 4 + test/snapshots/can_import_nested_modules.md | 348 ++++++------------ test/snapshots/multi_qualified_import.md | 121 ++---- .../nominal/nominal_import_long_package.md | 112 +----- .../qualified_type_canonicalization.md | 281 +++++++------- 10 files changed, 433 insertions(+), 617 deletions(-) diff --git a/src/canonicalize/Can.zig b/src/canonicalize/Can.zig index 37a643f3f4..f17aed82d0 100644 --- a/src/canonicalize/Can.zig +++ b/src/canonicalize/Can.zig @@ -1596,7 +1596,7 @@ fn bringIngestedFileIntoScope( fn processModuleImport( self: *Self, module_name: Ident.Idx, - alias: Ident.Idx, + alias: ?Ident.Idx, exposed_items_span: CIR.ExposedItem.Span, import_region: Region, ) std.mem.Allocator.Error!Statement.Idx { @@ -1609,14 +1609,16 @@ fn processModuleImport( module_name_text, ); - // 2. Add to scope: alias -> module_name mapping - try self.scopeIntroduceModuleAlias(alias, module_name); + // 2. Add to scope: alias -> module_name mapping (skip if no alias) + if (alias) |alias_ident| { + try self.scopeIntroduceModuleAlias(alias_ident, module_name); - // 3. Process type imports from this module - try self.processTypeImports(module_name, alias); + // 3. Process type imports from this module + try self.processTypeImports(module_name, alias_ident); + } // 4. Introduce exposed items into scope (includes auto-expose for type modules) - try self.introduceExposedItemsIntoScope(exposed_items_span, module_name, alias, import_region); + try self.introduceExposedItemsIntoScope(exposed_items_span, module_name, alias, import_region, module_import_idx); // 5. Store the mapping from module name to Import.Idx try self.import_indices.put(self.env.gpa, module_name_text, module_import_idx); @@ -1722,7 +1724,11 @@ fn canonicalizeImportStatement( }; // 2. Determine the alias (either explicit or default to last part) - const alias = try self.resolveModuleAlias(import_stmt.alias_tok, module_name) orelse return null; + // When suppress_alias is true, skip creating an alias + const alias = if (import_stmt.suppress_alias) + null + else + try self.resolveModuleAlias(import_stmt.alias_tok, module_name) orelse return null; // 3. Convert exposed items to CIR const scratch_start = self.env.store.scratchExposedItemTop(); @@ -1850,35 +1856,44 @@ fn introduceExposedItemsIntoScope( self: *Self, exposed_items_span: CIR.ExposedItem.Span, module_name: Ident.Idx, - module_alias: Ident.Idx, + module_alias: ?Ident.Idx, import_region: Region, + module_import_idx: CIR.Import.Idx, ) std.mem.Allocator.Error!void { const exposed_items_slice = self.env.store.sliceExposedItems(exposed_items_span); + const current_scope = self.currentScope(); - // If we have module_envs, validate the imports if (self.module_envs) |envs_map| { - // Check if the module exists - if (!envs_map.contains(module_name)) { - // Module not found - Module existence check is already done in canonicalizeImportStatement, - // so there is no need to create another diagnostic here for module_not_found - return; - } + const module_entry = envs_map.get(module_name) orelse return; + const module_env = module_entry.env; - // Get the module's exposed_items - const module_env = envs_map.get(module_name).?.env; + // Only auto-expose the module's main type if we have a module alias + // For suppress_alias imports like `import json.Parser.Config`, skip this + if (module_alias) |alias_ident| { + switch (module_env.module_kind) { + .type_module => |main_type_ident| { + if (module_env.containsExposedById(main_type_ident)) { + const item_info = Scope.ExposedItemInfo{ + .module_name = module_name, + .original_name = main_type_ident, + }; + try self.scopeIntroduceExposedItem(alias_ident, item_info); - // For type modules, auto-introduce the main type with the alias name - switch (module_env.module_kind) { - .type_module => |main_type_ident| { - if (module_env.containsExposedById(main_type_ident)) { - const item_info = Scope.ExposedItemInfo{ - .module_name = module_name, - .original_name = main_type_ident, - }; - try self.scopeIntroduceExposedItem(module_alias, item_info); - } - }, - else => {}, + const target_node_idx = module_env.getExposedNodeIndexById(main_type_ident); + try self.setExternalTypeBinding( + current_scope, + alias_ident, + module_name, + main_type_ident, + target_node_idx, + module_import_idx, + import_region, + .module_was_found, + ); + } + }, + else => {}, + } } // Validate each exposed item diff --git a/src/canonicalize/test/node_store_test.zig b/src/canonicalize/test/node_store_test.zig index 9271aa8b61..96f4cced3d 100644 --- a/src/canonicalize/test/node_store_test.zig +++ b/src/canonicalize/test/node_store_test.zig @@ -790,6 +790,14 @@ test "NodeStore round trip - Diagnostics" { }, }); + try diagnostics.append(CIR.Diagnostic{ + .type_from_missing_module = .{ + .module_name = rand_ident_idx(), + .type_name = rand_ident_idx(), + .region = rand_region(), + }, + }); + // Test the round-trip for all diagnostics for (diagnostics.items) |diagnostic| { const idx = try store.addDiagnostic(diagnostic); diff --git a/src/parse/AST.zig b/src/parse/AST.zig index b67c03647c..fd63da3d6c 100644 --- a/src/parse/AST.zig +++ b/src/parse/AST.zig @@ -822,6 +822,9 @@ pub const Statement = union(enum) { qualifier_tok: ?Token.Idx, alias_tok: ?Token.Idx, exposes: ExposedItem.Span, + /// True when importing like `import json.Parser.Config` where Config is auto-exposed + /// but Parser should not become an alias (unlike `import json.Parser exposing [Config]`) + suppress_alias: bool, region: TokenizedRegion, }, type_decl: struct { diff --git a/src/parse/NodeStore.zig b/src/parse/NodeStore.zig index 437a835e4e..84905a0de2 100644 --- a/src/parse/NodeStore.zig +++ b/src/parse/NodeStore.zig @@ -1172,6 +1172,7 @@ pub fn getStatement(store: *const NodeStore, statement_idx: AST.Statement.Idx) A .start = exposes_start, .len = exposes_len, } }, + .suppress_alias = false, .region = node.region, } }; }, diff --git a/src/parse/Parser.zig b/src/parse/Parser.zig index e165e099b6..fbdf12b95e 100644 --- a/src/parse/Parser.zig +++ b/src/parse/Parser.zig @@ -977,48 +977,83 @@ fn parseStmtByType(self: *Parser, statementType: StatementType) Error!AST.Statem } if ((qualifier == null and self.peek() == .UpperIdent) or (qualifier != null and (self.peek() == .NoSpaceDotUpperIdent or self.peek() == .DotUpperIdent))) { var exposes = AST.ExposedItem.Span{ .span = base.DataSpan.empty() }; - const module_name_tok = self.pos; - // Handle 'as' clause if present - if (self.peekNext() == .KwAs) { - self.advance(); // Advance past UpperIdent - self.advance(); // Advance past KwAs - alias_tok = self.pos; - self.expect(.UpperIdent) catch { - const malformed = try self.pushMalformed(AST.Statement.Idx, .expected_upper_name_after_import_as, start); - return malformed; - }; - } else { - self.advance(); // Advance past identifier + var suppress_alias = false; + + // Parse all uppercase segments: first.Second.Third... + var prev_upper_tok: ?TokenIdx = null; + var module_name_tok = self.pos; + self.advance(); // Advance past first UpperIdent + + // Keep consuming additional .UpperIdent segments + while (self.peek() == .NoSpaceDotUpperIdent or self.peek() == .DotUpperIdent) { + prev_upper_tok = module_name_tok; + module_name_tok = self.pos; + self.advance(); } - // Handle 'exposing' clause if present (can occur with or without 'as') - if (self.peek() == .KwExposing) { - self.advance(); // Advance past KwExposing - self.expect(.OpenSquare) catch { - return try self.pushMalformed(AST.Statement.Idx, .import_exposing_no_open, start); - }; + // If we have multiple uppercase segments and no explicit 'as' or 'exposing', + // auto-expose the final segment + const has_explicit_clause = self.peek() == .KwAs or self.peek() == .KwExposing; + if (prev_upper_tok != null and !has_explicit_clause) { + // Auto-expose pattern: import json.Parser.Config + // Module is everything before the last segment, last segment is auto-exposed + const final_segment_tok = module_name_tok; + module_name_tok = prev_upper_tok.?; + suppress_alias = true; + + // Create exposed item for the final segment const scratch_top = self.store.scratchExposedItemTop(); - self.parseCollectionSpan(AST.ExposedItem.Idx, .CloseSquare, NodeStore.addScratchExposedItem, Parser.parseExposedItem) catch |err| { - switch (err) { - error.ExpectedNotFound => { - while (self.peek() != .CloseSquare and self.peek() != .EndOfFile) { - self.advance(); - } - self.expect(.CloseSquare) catch {}; - self.store.clearScratchExposedItemsFrom(scratch_top); - return try self.pushMalformed(AST.Statement.Idx, .import_exposing_no_close, start); - }, - error.OutOfMemory => return error.OutOfMemory, - error.TooNested => return error.TooNested, - } - }; + const exposed_item = try self.store.addExposedItem(.{ .upper_ident = .{ + .region = .{ .start = final_segment_tok, .end = final_segment_tok }, + .ident = final_segment_tok, + .as = null, + } }); + try self.store.addScratchExposedItem(exposed_item); exposes = try self.store.exposedItemSpanFrom(scratch_top); + } else { + // Normal import: handle 'as' and 'exposing' clauses + + // Handle 'as' clause if present + if (self.peek() == .KwAs) { + self.advance(); // Advance past KwAs + alias_tok = self.pos; + self.expect(.UpperIdent) catch { + const malformed = try self.pushMalformed(AST.Statement.Idx, .expected_upper_name_after_import_as, start); + return malformed; + }; + } + + // Handle 'exposing' clause if present (can occur with or without 'as') + if (self.peek() == .KwExposing) { + self.advance(); // Advance past KwExposing + self.expect(.OpenSquare) catch { + return try self.pushMalformed(AST.Statement.Idx, .import_exposing_no_open, start); + }; + const scratch_top = self.store.scratchExposedItemTop(); + self.parseCollectionSpan(AST.ExposedItem.Idx, .CloseSquare, NodeStore.addScratchExposedItem, Parser.parseExposedItem) catch |err| { + switch (err) { + error.ExpectedNotFound => { + while (self.peek() != .CloseSquare and self.peek() != .EndOfFile) { + self.advance(); + } + self.expect(.CloseSquare) catch {}; + self.store.clearScratchExposedItemsFrom(scratch_top); + return try self.pushMalformed(AST.Statement.Idx, .import_exposing_no_close, start); + }, + error.OutOfMemory => return error.OutOfMemory, + error.TooNested => return error.TooNested, + } + }; + exposes = try self.store.exposedItemSpanFrom(scratch_top); + } } + const statement_idx = try self.store.addStatement(.{ .import = .{ .module_name_tok = module_name_tok, .qualifier_tok = qualifier, .alias_tok = alias_tok, .exposes = exposes, + .suppress_alias = suppress_alias, .region = .{ .start = start, .end = self.pos }, } }); return statement_idx; diff --git a/src/parse/test/ast_node_store_test.zig b/src/parse/test/ast_node_store_test.zig index a8e15cdb22..aa48a21bb2 100644 --- a/src/parse/test/ast_node_store_test.zig +++ b/src/parse/test/ast_node_store_test.zig @@ -189,6 +189,7 @@ test "NodeStore round trip - Statement" { .qualifier_tok = null, .region = rand_region(), .exposes = AST.ExposedItem.Span{ .span = rand_span() }, + .suppress_alias = false, }, }); // Import with alias @@ -199,6 +200,7 @@ test "NodeStore round trip - Statement" { .qualifier_tok = null, .region = rand_region(), .exposes = AST.ExposedItem.Span{ .span = rand_span() }, + .suppress_alias = false, }, }); // Import with qualifier but no alias @@ -209,6 +211,7 @@ test "NodeStore round trip - Statement" { .qualifier_tok = rand_token_idx(), .region = rand_region(), .exposes = AST.ExposedItem.Span{ .span = rand_span() }, + .suppress_alias = false, }, }); // Import with both qualifier and alias @@ -219,6 +222,7 @@ test "NodeStore round trip - Statement" { .qualifier_tok = rand_token_idx(), .region = rand_region(), .exposes = AST.ExposedItem.Span{ .span = rand_span() }, + .suppress_alias = false, }, }); try statements.append(AST.Statement{ diff --git a/test/snapshots/can_import_nested_modules.md b/test/snapshots/can_import_nested_modules.md index 6b0aeae2a7..2aec43b7c7 100644 --- a/test/snapshots/can_import_nested_modules.md +++ b/test/snapshots/can_import_nested_modules.md @@ -31,197 +31,65 @@ validateAuth : HttpAuth.Credentials -> Result(HttpAuth.Token, HttpAuth.Error) validateAuth = |creds| HttpAuth.validate(creds) ~~~ # EXPECTED -PARSE ERROR - can_import_nested_modules.md:1:19:1:26 -PARSE ERROR - can_import_nested_modules.md:2:19:2:24 -PARSE ERROR - can_import_nested_modules.md:2:25:2:27 -PARSE ERROR - can_import_nested_modules.md:3:1:3:7 -PARSE ERROR - can_import_nested_modules.md:3:8:3:13 -PARSE ERROR - can_import_nested_modules.md:3:13:3:20 -PARSE ERROR - can_import_nested_modules.md:3:20:3:27 -PARSE ERROR - can_import_nested_modules.md:3:28:3:36 -PARSE ERROR - can_import_nested_modules.md:3:37:3:38 -PARSE ERROR - can_import_nested_modules.md:3:38:3:45 -PARSE ERROR - can_import_nested_modules.md:3:45:3:46 -MODULE NOT FOUND - can_import_nested_modules.md:1:1:1:19 -MODULE NOT FOUND - can_import_nested_modules.md:2:1:2:19 -MODULE NOT IMPORTED - can_import_nested_modules.md:6:15:6:30 +MODULE NOT FOUND - can_import_nested_modules.md:1:1:1:26 +MODULE NOT FOUND - can_import_nested_modules.md:2:1:2:36 +MODULE NOT FOUND - can_import_nested_modules.md:3:1:3:46 +UNDECLARED TYPE - can_import_nested_modules.md:6:21:6:30 UNDEFINED VARIABLE - can_import_nested_modules.md:7:26:7:41 -MODULE NOT IMPORTED - can_import_nested_modules.md:10:28:10:42 +TYPE NOT EXPOSED - can_import_nested_modules.md:10:36:10:42 UNDEFINED VARIABLE - can_import_nested_modules.md:11:29:11:43 -MODULE NOT IMPORTED - can_import_nested_modules.md:14:15:14:37 -MODULE NOT IMPORTED - can_import_nested_modules.md:14:58:14:77 +UNDECLARED TYPE - can_import_nested_modules.md:14:28:14:37 +UNDECLARED TYPE - can_import_nested_modules.md:14:71:14:77 UNDEFINED VARIABLE - can_import_nested_modules.md:16:5:16:37 UNDEFINED VARIABLE - can_import_nested_modules.md:20:23:20:30 UNDEFINED VARIABLE - can_import_nested_modules.md:20:37:20:58 -MODULE NOT IMPORTED - can_import_nested_modules.md:23:16:23:36 -MODULE NOT IMPORTED - can_import_nested_modules.md:23:47:23:61 -MODULE NOT IMPORTED - can_import_nested_modules.md:23:63:23:77 +TYPE NOT EXPOSED - can_import_nested_modules.md:23:24:23:36 +TYPE NOT EXPOSED - can_import_nested_modules.md:23:55:23:61 +TYPE NOT EXPOSED - can_import_nested_modules.md:23:71:23:77 UNDEFINED VARIABLE - can_import_nested_modules.md:24:24:24:41 # PROBLEMS -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**can_import_nested_modules.md:1:19:1:26:** -```roc -import json.Parser.Config -``` - ^^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**can_import_nested_modules.md:2:19:2:24:** -```roc -import http.Client.Auth as HttpAuth -``` - ^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**can_import_nested_modules.md:2:25:2:27:** -```roc -import http.Client.Auth as HttpAuth -``` - ^^ - - -**PARSE ERROR** -Type applications require parentheses around their type arguments. - -I found a type followed by what looks like a type argument, but they need to be connected with parentheses. - -Instead of: - **List U8** - -Use: - **List(U8)** - -Other valid examples: - `Dict(Str, Num)` - `Result(a, Str)` - `Maybe(List(U64))` - -**can_import_nested_modules.md:3:1:3:7:** -```roc -import utils.String.Format exposing [padLeft] -``` -^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**can_import_nested_modules.md:3:8:3:13:** -```roc -import utils.String.Format exposing [padLeft] -``` - ^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**can_import_nested_modules.md:3:13:3:20:** -```roc -import utils.String.Format exposing [padLeft] -``` - ^^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**can_import_nested_modules.md:3:20:3:27:** -```roc -import utils.String.Format exposing [padLeft] -``` - ^^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**can_import_nested_modules.md:3:28:3:36:** -```roc -import utils.String.Format exposing [padLeft] -``` - ^^^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**can_import_nested_modules.md:3:37:3:38:** -```roc -import utils.String.Format exposing [padLeft] -``` - ^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**can_import_nested_modules.md:3:38:3:45:** -```roc -import utils.String.Format exposing [padLeft] -``` - ^^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**can_import_nested_modules.md:3:45:3:46:** -```roc -import utils.String.Format exposing [padLeft] -``` - ^ - - **MODULE NOT FOUND** The module `json.Parser` was not found in this Roc project. You're attempting to use this module here: -**can_import_nested_modules.md:1:1:1:19:** +**can_import_nested_modules.md:1:1:1:26:** ```roc import json.Parser.Config ``` -^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^ **MODULE NOT FOUND** -The module `http.Client` was not found in this Roc project. +The module `http.Client.Auth` was not found in this Roc project. You're attempting to use this module here: -**can_import_nested_modules.md:2:1:2:19:** +**can_import_nested_modules.md:2:1:2:36:** ```roc import http.Client.Auth as HttpAuth ``` -^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `Config` imported into this Roc file. +**MODULE NOT FOUND** +The module `utils.String.Format` was not found in this Roc project. You're attempting to use this module here: -**can_import_nested_modules.md:6:15:6:30:** +**can_import_nested_modules.md:3:1:3:46:** +```roc +import utils.String.Format exposing [padLeft] +``` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +**UNDECLARED TYPE** +The type _Config.Settings_ is not declared in this scope. + +This type is referenced here: +**can_import_nested_modules.md:6:21:6:30:** ```roc parseConfig : Config.Settings -> Str ``` - ^^^^^^^^^^^^^^^ + ^^^^^^^^^ **UNDEFINED VARIABLE** @@ -235,15 +103,15 @@ parseConfig = |settings| Config.toString(settings) ^^^^^^^^^^^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `HttpAuth` imported into this Roc file. +**TYPE NOT EXPOSED** +The type `Token` is not an exposed by the module `http.Client.Auth`. -You're attempting to use this module here: -**can_import_nested_modules.md:10:28:10:42:** +You're attempting to use this type here: +**can_import_nested_modules.md:10:36:10:42:** ```roc authenticate : Str, Str -> HttpAuth.Token ``` - ^^^^^^^^^^^^^^ + ^^^^^^ **UNDEFINED VARIABLE** @@ -257,26 +125,26 @@ authenticate = |user, pass| HttpAuth.login(user, pass) ^^^^^^^^^^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `Config.Parser` imported into this Roc file. +**UNDECLARED TYPE** +The type _Config.Parser.Advanced_ is not declared in this scope. -You're attempting to use this module here: -**can_import_nested_modules.md:14:15:14:37:** +This type is referenced here: +**can_import_nested_modules.md:14:28:14:37:** ```roc processData : Config.Parser.Advanced, Str -> Result(Str, Config.Parser.Error) ``` - ^^^^^^^^^^^^^^^^^^^^^^ + ^^^^^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `Config.Parser` imported into this Roc file. +**UNDECLARED TYPE** +The type _Config.Parser.Error_ is not declared in this scope. -You're attempting to use this module here: -**can_import_nested_modules.md:14:58:14:77:** +This type is referenced here: +**can_import_nested_modules.md:14:71:14:77:** ```roc processData : Config.Parser.Advanced, Str -> Result(Str, Config.Parser.Error) ``` - ^^^^^^^^^^^^^^^^^^^ + ^^^^^^ **UNDEFINED VARIABLE** @@ -312,37 +180,37 @@ formatOutput = |text| padLeft(text, Config.defaultPadding) ^^^^^^^^^^^^^^^^^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `HttpAuth` imported into this Roc file. +**TYPE NOT EXPOSED** +The type `Credentials` is not an exposed by the module `http.Client.Auth`. -You're attempting to use this module here: -**can_import_nested_modules.md:23:16:23:36:** +You're attempting to use this type here: +**can_import_nested_modules.md:23:24:23:36:** ```roc validateAuth : HttpAuth.Credentials -> Result(HttpAuth.Token, HttpAuth.Error) ``` - ^^^^^^^^^^^^^^^^^^^^ + ^^^^^^^^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `HttpAuth` imported into this Roc file. +**TYPE NOT EXPOSED** +The type `Token` is not an exposed by the module `http.Client.Auth`. -You're attempting to use this module here: -**can_import_nested_modules.md:23:47:23:61:** +You're attempting to use this type here: +**can_import_nested_modules.md:23:55:23:61:** ```roc validateAuth : HttpAuth.Credentials -> Result(HttpAuth.Token, HttpAuth.Error) ``` - ^^^^^^^^^^^^^^ + ^^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `HttpAuth` imported into this Roc file. +**TYPE NOT EXPOSED** +The type `Error` is not an exposed by the module `http.Client.Auth`. -You're attempting to use this module here: -**can_import_nested_modules.md:23:63:23:77:** +You're attempting to use this type here: +**can_import_nested_modules.md:23:71:23:77:** ```roc validateAuth : HttpAuth.Credentials -> Result(HttpAuth.Token, HttpAuth.Error) ``` - ^^^^^^^^^^^^^^ + ^^^^^^ **UNDEFINED VARIABLE** @@ -379,19 +247,14 @@ EndOfFile, (file (type-module) (statements - (s-import (raw "json.Parser")) - (s-malformed (tag "statement_unexpected_token")) - (s-import (raw "http.Client")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "expected_colon_after_type_annotation")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) + (s-import (raw "json.Parser") + (exposing + (exposed-upper-ident (text "Config")))) + (s-import (raw "http.Auth") (alias "HttpAuth")) + (s-import (raw "utils.Format") + (exposing + (exposed-lower-ident + (text "padLeft")))) (s-type-anno (name "parseConfig") (ty-fn (ty (name "Config.Settings")) @@ -468,11 +331,9 @@ EndOfFile, ~~~ # FORMATTED ~~~roc -import json.Parser - -import http.Client - - +import json.Parser exposing [Config] +import http.Auth as HttpAuth +import utils.Format exposing [padLeft] # Test multi-level type qualification parseConfig : Config.Settings -> Str @@ -508,9 +369,10 @@ validateAuth = |creds| HttpAuth.validate(creds) (e-lookup-local (p-assign (ident "settings"))))) (annotation - (ty-fn (effectful false) - (ty-malformed) - (ty-lookup (name "Str") (builtin))))) + (declared-type + (ty-fn (effectful false) + (ty-malformed) + (ty-lookup (name "Str") (builtin)))))) (d-let (p-assign (ident "authenticate")) (e-lambda @@ -524,10 +386,11 @@ validateAuth = |creds| HttpAuth.validate(creds) (e-lookup-local (p-assign (ident "pass"))))) (annotation - (ty-fn (effectful false) - (ty-lookup (name "Str") (builtin)) - (ty-lookup (name "Str") (builtin)) - (ty-malformed)))) + (declared-type + (ty-fn (effectful false) + (ty-lookup (name "Str") (builtin)) + (ty-lookup (name "Str") (builtin)) + (ty-malformed))))) (d-let (p-assign (ident "processData")) (e-lambda @@ -541,12 +404,13 @@ validateAuth = |creds| HttpAuth.validate(creds) (e-lookup-local (p-assign (ident "input"))))) (annotation - (ty-fn (effectful false) - (ty-malformed) - (ty-lookup (name "Str") (builtin)) - (ty-apply (name "Result") (external-module "Result") + (declared-type + (ty-fn (effectful false) + (ty-malformed) (ty-lookup (name "Str") (builtin)) - (ty-malformed))))) + (ty-apply (name "Result") (external-module "Result") + (ty-lookup (name "Str") (builtin)) + (ty-malformed)))))) (d-let (p-assign (ident "formatOutput")) (e-lambda @@ -558,9 +422,10 @@ validateAuth = |creds| HttpAuth.validate(creds) (p-assign (ident "text"))) (e-runtime-error (tag "ident_not_in_scope")))) (annotation - (ty-fn (effectful false) - (ty-lookup (name "Str") (builtin)) - (ty-lookup (name "Str") (builtin))))) + (declared-type + (ty-fn (effectful false) + (ty-lookup (name "Str") (builtin)) + (ty-lookup (name "Str") (builtin)))))) (d-let (p-assign (ident "validateAuth")) (e-lambda @@ -571,29 +436,34 @@ validateAuth = |creds| HttpAuth.validate(creds) (e-lookup-local (p-assign (ident "creds"))))) (annotation - (ty-fn (effectful false) - (ty-malformed) - (ty-apply (name "Result") (external-module "Result") + (declared-type + (ty-fn (effectful false) (ty-malformed) - (ty-malformed))))) + (ty-apply (name "Result") (external-module "Result") + (ty-malformed) + (ty-malformed)))))) (s-import (module "json.Parser") + (exposes + (exposed (name "Config") (wildcard false)))) + (s-import (module "http.Client.Auth") (exposes)) - (s-import (module "http.Client") - (exposes))) + (s-import (module "utils.String.Format") + (exposes + (exposed (name "padLeft") (wildcard false))))) ~~~ # TYPES ~~~clojure (inferred-types (defs - (patt (type "Error -> Error")) + (patt (type "Error -> Str")) (patt (type "Str, Str -> Error")) - (patt (type "Error, Str -> Error")) - (patt (type "Str -> Error")) - (patt (type "Error -> Error"))) + (patt (type "Error, Str -> Result(Str, Error)")) + (patt (type "Str -> Str")) + (patt (type "Error -> Result(Error, Error)"))) (expressions - (expr (type "Error -> Error")) + (expr (type "Error -> Str")) (expr (type "Str, Str -> Error")) - (expr (type "Error, Str -> Error")) - (expr (type "Str -> Error")) - (expr (type "Error -> Error")))) + (expr (type "Error, Str -> Result(Str, Error)")) + (expr (type "Str -> Str")) + (expr (type "Error -> Result(Error, Error)")))) ~~~ diff --git a/test/snapshots/multi_qualified_import.md b/test/snapshots/multi_qualified_import.md index 67c84e4e64..70ae4112e3 100644 --- a/test/snapshots/multi_qualified_import.md +++ b/test/snapshots/multi_qualified_import.md @@ -19,10 +19,6 @@ data : json.Core.Utf8.EncodedData data = json.Core.Utf8.encode("hello") ~~~ # EXPECTED -PARSE ERROR - multi_qualified_import.md:1:17:1:22 -PARSE ERROR - multi_qualified_import.md:1:23:1:31 -PARSE ERROR - multi_qualified_import.md:1:32:1:33 -PARSE ERROR - multi_qualified_import.md:1:40:1:41 PARSE ERROR - multi_qualified_import.md:12:12:12:17 PARSE ERROR - multi_qualified_import.md:12:17:12:22 PARSE ERROR - multi_qualified_import.md:12:22:12:29 @@ -31,74 +27,18 @@ PARSE ERROR - multi_qualified_import.md:12:30:12:31 PARSE ERROR - multi_qualified_import.md:12:31:12:36 PARSE ERROR - multi_qualified_import.md:12:36:12:37 PARSE ERROR - multi_qualified_import.md:12:37:12:38 -MODULE NOT FOUND - multi_qualified_import.md:1:1:1:17 +MODULE NOT FOUND - multi_qualified_import.md:1:1:1:41 UNDECLARED TYPE - multi_qualified_import.md:3:16:3:23 UNDEFINED VARIABLE - multi_qualified_import.md:4:16:4:45 -MODULE NOT IMPORTED - multi_qualified_import.md:7:11:7:33 +UNDECLARED TYPE - multi_qualified_import.md:7:25:7:33 UNUSED VARIABLE - multi_qualified_import.md:8:12:8:19 -MODULE NOT IMPORTED - multi_qualified_import.md:11:8:11:34 +UNDECLARED TYPE - multi_qualified_import.md:11:22:11:34 UNDEFINED VARIABLE - multi_qualified_import.md:12:8:12:12 # PROBLEMS **PARSE ERROR** A parsing error occurred: `statement_unexpected_token` This is an unexpected parsing error. Please check your syntax. -**multi_qualified_import.md:1:17:1:22:** -```roc -import json.Core.Utf8 exposing [Encoder] -``` - ^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**multi_qualified_import.md:1:23:1:31:** -```roc -import json.Core.Utf8 exposing [Encoder] -``` - ^^^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**multi_qualified_import.md:1:32:1:33:** -```roc -import json.Core.Utf8 exposing [Encoder] -``` - ^ - - -**PARSE ERROR** -Type applications require parentheses around their type arguments. - -I found a type followed by what looks like a type argument, but they need to be connected with parentheses. - -Instead of: - **List U8** - -Use: - **List(U8)** - -Other valid examples: - `Dict(Str, Num)` - `Result(a, Str)` - `Maybe(List(U64))` - -**multi_qualified_import.md:1:40:1:41:** -```roc -import json.Core.Utf8 exposing [Encoder] -``` - ^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - **multi_qualified_import.md:12:12:12:17:** ```roc data = json.Core.Utf8.encode("hello") @@ -184,14 +124,14 @@ data = json.Core.Utf8.encode("hello") **MODULE NOT FOUND** -The module `json.Core` was not found in this Roc project. +The module `json.Core.Utf8` was not found in this Roc project. You're attempting to use this module here: -**multi_qualified_import.md:1:1:1:17:** +**multi_qualified_import.md:1:1:1:41:** ```roc import json.Core.Utf8 exposing [Encoder] ``` -^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **UNDECLARED TYPE** @@ -216,15 +156,15 @@ json_encoder = Json.Core.Utf8.defaultEncoder ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `json.Core.Utf8` imported into this Roc file. +**UNDECLARED TYPE** +The type _json.Core.Utf8.Encoder_ is not declared in this scope. -You're attempting to use this module here: -**multi_qualified_import.md:7:11:7:33:** +This type is referenced here: +**multi_qualified_import.md:7:25:7:33:** ```roc process : json.Core.Utf8.Encoder -> Str ``` - ^^^^^^^^^^^^^^^^^^^^^^ + ^^^^^^^^ **UNUSED VARIABLE** @@ -239,15 +179,15 @@ process = |encoder| "processing" ^^^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `json.Core.Utf8` imported into this Roc file. +**UNDECLARED TYPE** +The type _json.Core.Utf8.EncodedData_ is not declared in this scope. -You're attempting to use this module here: -**multi_qualified_import.md:11:8:11:34:** +This type is referenced here: +**multi_qualified_import.md:11:22:11:34:** ```roc data : json.Core.Utf8.EncodedData ``` - ^^^^^^^^^^^^^^^^^^^^^^^^^^ + ^^^^^^^^^^^^ **UNDEFINED VARIABLE** @@ -277,11 +217,9 @@ EndOfFile, (file (type-module) (statements - (s-import (raw "json.Core")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "expected_colon_after_type_annotation")) + (s-import (raw "json.Utf8") + (exposing + (exposed-upper-ident (text "Encoder")))) (s-type-anno (name "json_encoder") (ty (name "Encoder"))) (s-decl @@ -314,8 +252,7 @@ EndOfFile, ~~~ # FORMATTED ~~~roc -import json.Core - +import json.Utf8 exposing [Encoder] json_encoder : Encoder json_encoder = Json.Core.Utf8.defaultEncoder @@ -335,7 +272,8 @@ data = json (p-assign (ident "json_encoder")) (e-runtime-error (tag "ident_not_in_scope")) (annotation - (ty-malformed))) + (declared-type + (ty-malformed)))) (d-let (p-assign (ident "process")) (e-lambda @@ -344,16 +282,19 @@ data = json (e-string (e-literal (string "processing")))) (annotation - (ty-fn (effectful false) - (ty-malformed) - (ty-lookup (name "Str") (builtin))))) + (declared-type + (ty-fn (effectful false) + (ty-malformed) + (ty-lookup (name "Str") (builtin)))))) (d-let (p-assign (ident "data")) (e-runtime-error (tag "ident_not_in_scope")) (annotation - (ty-malformed))) - (s-import (module "json.Core") - (exposes))) + (declared-type + (ty-malformed)))) + (s-import (module "json.Core.Utf8") + (exposes + (exposed (name "Encoder") (wildcard false))))) ~~~ # TYPES ~~~clojure diff --git a/test/snapshots/nominal/nominal_import_long_package.md b/test/snapshots/nominal/nominal_import_long_package.md index 2af5be1aaf..6d3bd6e837 100644 --- a/test/snapshots/nominal/nominal_import_long_package.md +++ b/test/snapshots/nominal/nominal_import_long_package.md @@ -11,102 +11,18 @@ red : CE red = ... # not implemented ~~~ # EXPECTED -PARSE ERROR - nominal_import_long_package.md:1:21:1:27 -PARSE ERROR - nominal_import_long_package.md:1:28:1:36 -PARSE ERROR - nominal_import_long_package.md:1:37:1:38 -PARSE ERROR - nominal_import_long_package.md:1:46:1:48 -PARSE ERROR - nominal_import_long_package.md:1:51:1:52 -MODULE NOT FOUND - nominal_import_long_package.md:1:1:1:21 +MODULE NOT FOUND - nominal_import_long_package.md:1:1:1:52 UNDECLARED TYPE - nominal_import_long_package.md:3:7:3:9 # PROBLEMS -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**nominal_import_long_package.md:1:21:1:27:** -```roc -import design.Styles.Color exposing [Encoder as CE] -``` - ^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**nominal_import_long_package.md:1:28:1:36:** -```roc -import design.Styles.Color exposing [Encoder as CE] -``` - ^^^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**nominal_import_long_package.md:1:37:1:38:** -```roc -import design.Styles.Color exposing [Encoder as CE] -``` - ^ - - -**PARSE ERROR** -Type applications require parentheses around their type arguments. - -I found a type followed by what looks like a type argument, but they need to be connected with parentheses. - -Instead of: - **List U8** - -Use: - **List(U8)** - -Other valid examples: - `Dict(Str, Num)` - `Result(a, Str)` - `Maybe(List(U64))` - -**nominal_import_long_package.md:1:46:1:48:** -```roc -import design.Styles.Color exposing [Encoder as CE] -``` - ^^ - - -**PARSE ERROR** -Type applications require parentheses around their type arguments. - -I found a type followed by what looks like a type argument, but they need to be connected with parentheses. - -Instead of: - **List U8** - -Use: - **List(U8)** - -Other valid examples: - `Dict(Str, Num)` - `Result(a, Str)` - `Maybe(List(U64))` - -**nominal_import_long_package.md:1:51:1:52:** -```roc -import design.Styles.Color exposing [Encoder as CE] -``` - ^ - - **MODULE NOT FOUND** -The module `design.Styles` was not found in this Roc project. +The module `design.Styles.Color` was not found in this Roc project. You're attempting to use this module here: -**nominal_import_long_package.md:1:1:1:21:** +**nominal_import_long_package.md:1:1:1:52:** ```roc import design.Styles.Color exposing [Encoder as CE] ``` -^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **UNDECLARED TYPE** @@ -132,12 +48,9 @@ EndOfFile, (file (type-module) (statements - (s-import (raw "design.Styles")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "expected_colon_after_type_annotation")) - (s-malformed (tag "expected_colon_after_type_annotation")) + (s-import (raw "design.Color") + (exposing + (exposed-upper-ident (text "Encoder") (as "CE")))) (s-type-anno (name "red") (ty (name "CE"))) (s-decl @@ -146,8 +59,7 @@ EndOfFile, ~~~ # FORMATTED ~~~roc -import design.Styles - +import design.Color exposing [Encoder as CE] red : CE red = ... # not implemented @@ -159,9 +71,11 @@ red = ... # not implemented (p-assign (ident "red")) (e-not-implemented) (annotation - (ty-malformed))) - (s-import (module "design.Styles") - (exposes))) + (declared-type + (ty-malformed)))) + (s-import (module "design.Styles.Color") + (exposes + (exposed (name "Encoder") (alias "CE") (wildcard false))))) ~~~ # TYPES ~~~clojure diff --git a/test/snapshots/qualified_type_canonicalization.md b/test/snapshots/qualified_type_canonicalization.md index 9effbf2491..3b829b330a 100644 --- a/test/snapshots/qualified_type_canonicalization.md +++ b/test/snapshots/qualified_type_canonicalization.md @@ -53,22 +53,25 @@ transform = |result| # EXPECTED PARSE ERROR - qualified_type_canonicalization.md:8:1:8:7 PARSE ERROR - qualified_type_canonicalization.md:8:14:8:21 -PARSE ERROR - qualified_type_canonicalization.md:10:15:10:23 -PARSE ERROR - qualified_type_canonicalization.md:10:24:10:32 -PARSE ERROR - qualified_type_canonicalization.md:10:33:10:34 -PARSE ERROR - qualified_type_canonicalization.md:10:39:10:40 MODULE NOT FOUND - qualified_type_canonicalization.md:9:1:9:13 -MODULE NOT FOUND - qualified_type_canonicalization.md:10:1:10:15 +MODULE NOT FOUND - qualified_type_canonicalization.md:10:1:10:40 MODULE NOT FOUND - qualified_type_canonicalization.md:11:1:11:32 +TYPE NOT EXPOSED - qualified_type_canonicalization.md:14:24:14:28 UNDECLARED TYPE - qualified_type_canonicalization.md:15:19:15:24 -MODULE NOT IMPORTED - qualified_type_canonicalization.md:22:23:22:44 +TYPE NOT EXPOSED - qualified_type_canonicalization.md:18:26:18:35 +UNDECLARED TYPE - qualified_type_canonicalization.md:19:26:19:35 +UNDECLARED TYPE - qualified_type_canonicalization.md:22:38:22:44 UNDEFINED VARIABLE - qualified_type_canonicalization.md:23:23:23:32 +TYPE NOT EXPOSED - qualified_type_canonicalization.md:26:20:26:27 +TYPE NOT EXPOSED - qualified_type_canonicalization.md:30:23:30:27 UNDECLARED TYPE - qualified_type_canonicalization.md:31:16:31:21 +TYPE NOT EXPOSED - qualified_type_canonicalization.md:34:21:34:25 UNUSED VARIABLE - qualified_type_canonicalization.md:35:17:35:22 -MODULE NOT IMPORTED - qualified_type_canonicalization.md:39:55:39:76 -UNDECLARED TYPE - qualified_type_canonicalization.md:42:9:42:15 +TYPE NOT EXPOSED - qualified_type_canonicalization.md:39:19:39:26 +TYPE NOT EXPOSED - qualified_type_canonicalization.md:39:32:39:36 +TYPE NOT EXPOSED - qualified_type_canonicalization.md:39:44:39:50 +UNDECLARED TYPE - qualified_type_canonicalization.md:39:70:39:76 UNDEFINED VARIABLE - qualified_type_canonicalization.md:42:27:42:42 -UNDECLARED TYPE - qualified_type_canonicalization.md:43:9:43:15 UNDEFINED VARIABLE - qualified_type_canonicalization.md:43:28:43:41 UNUSED VARIABLE - qualified_type_canonicalization.md:43:20:43:23 # PROBLEMS @@ -106,62 +109,6 @@ import Basics.Result ^^^^^^^ -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**qualified_type_canonicalization.md:10:15:10:23:** -```roc -import ModuleA.ModuleB exposing [TypeC] -``` - ^^^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**qualified_type_canonicalization.md:10:24:10:32:** -```roc -import ModuleA.ModuleB exposing [TypeC] -``` - ^^^^^^^^ - - -**PARSE ERROR** -A parsing error occurred: `statement_unexpected_token` -This is an unexpected parsing error. Please check your syntax. - -**qualified_type_canonicalization.md:10:33:10:34:** -```roc -import ModuleA.ModuleB exposing [TypeC] -``` - ^ - - -**PARSE ERROR** -Type applications require parentheses around their type arguments. - -I found a type followed by what looks like a type argument, but they need to be connected with parentheses. - -Instead of: - **List U8** - -Use: - **List(U8)** - -Other valid examples: - `Dict(Str, Num)` - `Result(a, Str)` - `Maybe(List(U64))` - -**qualified_type_canonicalization.md:10:39:10:40:** -```roc -import ModuleA.ModuleB exposing [TypeC] -``` - ^ - - **MODULE NOT FOUND** The module `Color` was not found in this Roc project. @@ -174,14 +121,14 @@ import Color **MODULE NOT FOUND** -The module `ModuleA` was not found in this Roc project. +The module `ModuleB` was not found in this Roc project. You're attempting to use this module here: -**qualified_type_canonicalization.md:10:1:10:15:** +**qualified_type_canonicalization.md:10:1:10:40:** ```roc import ModuleA.ModuleB exposing [TypeC] ``` -^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **MODULE NOT FOUND** @@ -195,6 +142,17 @@ import ExternalModule as ExtMod ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**TYPE NOT EXPOSED** +The type `RGB` is not an exposed by the module `Color`. + +You're attempting to use this type here: +**qualified_type_canonicalization.md:14:24:14:28:** +```roc +simpleQualified : Color.RGB +``` + ^^^^ + + **UNDECLARED TYPE** The type _Color_ is not declared in this scope. @@ -206,15 +164,37 @@ simpleQualified = Color.RGB({ r: 255, g: 0, b: 0 }) ^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `ModuleA.ModuleB` imported into this Roc file. +**TYPE NOT EXPOSED** +The type `DataType` is not an exposed by the module `ExternalModule`. -You're attempting to use this module here: -**qualified_type_canonicalization.md:22:23:22:44:** +You're attempting to use this type here: +**qualified_type_canonicalization.md:18:26:18:35:** +```roc +aliasedQualified : ExtMod.DataType +``` + ^^^^^^^^^ + + +**UNDECLARED TYPE** +The type _ExtMod.DataType_ is not declared in this scope. + +This type is referenced here: +**qualified_type_canonicalization.md:19:26:19:35:** +```roc +aliasedQualified = ExtMod.DataType.Default +``` + ^^^^^^^^^ + + +**UNDECLARED TYPE** +The type _ModuleA.ModuleB.TypeC_ is not declared in this scope. + +This type is referenced here: +**qualified_type_canonicalization.md:22:38:22:44:** ```roc multiLevelQualified : ModuleA.ModuleB.TypeC ``` - ^^^^^^^^^^^^^^^^^^^^^ + ^^^^^^ **UNDEFINED VARIABLE** @@ -228,6 +208,28 @@ multiLevelQualified = TypeC.new ^^^^^^^^^ +**TYPE NOT EXPOSED** +The type `Result` is not an exposed by the module `Result`. + +You're attempting to use this type here: +**qualified_type_canonicalization.md:26:20:26:27:** +```roc +resultType : Result.Result(I32, Str) +``` + ^^^^^^^ + + +**TYPE NOT EXPOSED** +The type `RGB` is not an exposed by the module `Color`. + +You're attempting to use this type here: +**qualified_type_canonicalization.md:30:23:30:27:** +```roc +getColor : {} -> Color.RGB +``` + ^^^^ + + **UNDECLARED TYPE** The type _Color_ is not declared in this scope. @@ -239,6 +241,17 @@ getColor = |_| Color.RGB({ r: 0, g: 255, b: 0 }) ^^^^^ +**TYPE NOT EXPOSED** +The type `RGB` is not an exposed by the module `Color`. + +You're attempting to use this type here: +**qualified_type_canonicalization.md:34:21:34:25:** +```roc +processColor : Color.RGB -> Str +``` + ^^^^ + + **UNUSED VARIABLE** Variable `color` is not used anywhere in your code. @@ -251,26 +264,48 @@ processColor = |color| ^^^^^ -**MODULE NOT IMPORTED** -There is no module with the name `ModuleA.ModuleB` imported into this Roc file. +**TYPE NOT EXPOSED** +The type `Result` is not an exposed by the module `Result`. -You're attempting to use this module here: -**qualified_type_canonicalization.md:39:55:39:76:** +You're attempting to use this type here: +**qualified_type_canonicalization.md:39:19:39:26:** ```roc transform : Result.Result(Color.RGB, ExtMod.Error) -> ModuleA.ModuleB.TypeC ``` - ^^^^^^^^^^^^^^^^^^^^^ + ^^^^^^^ + + +**TYPE NOT EXPOSED** +The type `RGB` is not an exposed by the module `Color`. + +You're attempting to use this type here: +**qualified_type_canonicalization.md:39:32:39:36:** +```roc +transform : Result.Result(Color.RGB, ExtMod.Error) -> ModuleA.ModuleB.TypeC +``` + ^^^^ + + +**TYPE NOT EXPOSED** +The type `Error` is not an exposed by the module `ExternalModule`. + +You're attempting to use this type here: +**qualified_type_canonicalization.md:39:44:39:50:** +```roc +transform : Result.Result(Color.RGB, ExtMod.Error) -> ModuleA.ModuleB.TypeC +``` + ^^^^^^ **UNDECLARED TYPE** -The type _Result_ is not declared in this scope. +The type _ModuleA.ModuleB.TypeC_ is not declared in this scope. This type is referenced here: -**qualified_type_canonicalization.md:42:9:42:15:** +**qualified_type_canonicalization.md:39:70:39:76:** ```roc - Result.Ok(rgb) => TypeC.fromColor(rgb) +transform : Result.Result(Color.RGB, ExtMod.Error) -> ModuleA.ModuleB.TypeC ``` - ^^^^^^ + ^^^^^^ **UNDEFINED VARIABLE** @@ -284,17 +319,6 @@ Is there an `import` or `exposing` missing up-top? ^^^^^^^^^^^^^^^ -**UNDECLARED TYPE** -The type _Result_ is not declared in this scope. - -This type is referenced here: -**qualified_type_canonicalization.md:43:9:43:15:** -```roc - Result.Err(err) => TypeC.default -``` - ^^^^^^ - - **UNDEFINED VARIABLE** Nothing is named `default` in this scope. Is there an `import` or `exposing` missing up-top? @@ -358,11 +382,9 @@ EndOfFile, (statements (s-malformed (tag "expected_colon_after_type_annotation")) (s-import (raw "Color")) - (s-import (raw "ModuleA")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "statement_unexpected_token")) - (s-malformed (tag "expected_colon_after_type_annotation")) + (s-import (raw ".ModuleB") + (exposing + (exposed-upper-ident (text "TypeC")))) (s-import (raw "ExternalModule") (alias "ExtMod")) (s-type-anno (name "simpleQualified") (ty (name "Color.RGB"))) @@ -456,8 +478,7 @@ EndOfFile, ~~~roc import Color -import ModuleA - +import ModuleB exposing [TypeC] import ExternalModule as ExtMod # Simple qualified type @@ -500,19 +521,20 @@ transform = |result| (p-assign (ident "simpleQualified")) (e-runtime-error (tag "undeclared_type")) (annotation - (ty-lookup (name "RGB") (external-module "Color")))) + (declared-type + (ty-malformed)))) (d-let (p-assign (ident "aliasedQualified")) - (e-nominal-external - (external-module "ExternalModule") - (e-tag (name "Default"))) + (e-runtime-error (tag "undeclared_type")) (annotation - (ty-lookup (name "DataType") (external-module "ExternalModule")))) + (declared-type + (ty-malformed)))) (d-let (p-assign (ident "multiLevelQualified")) (e-runtime-error (tag "ident_not_in_scope")) (annotation - (ty-malformed))) + (declared-type + (ty-malformed)))) (d-let (p-assign (ident "resultType")) (e-nominal-external @@ -521,9 +543,8 @@ transform = |result| (args (e-num (value "42"))))) (annotation - (ty-apply (name "Result") (external-module "Result") - (ty-lookup (name "I32") (builtin)) - (ty-lookup (name "Str") (builtin))))) + (declared-type + (ty-malformed)))) (d-let (p-assign (ident "getColor")) (e-lambda @@ -531,9 +552,10 @@ transform = |result| (p-underscore)) (e-runtime-error (tag "undeclared_type"))) (annotation - (ty-fn (effectful false) - (ty-record) - (ty-lookup (name "RGB") (external-module "Color"))))) + (declared-type + (ty-fn (effectful false) + (ty-record) + (ty-malformed))))) (d-let (p-assign (ident "processColor")) (e-lambda @@ -542,9 +564,10 @@ transform = |result| (e-string (e-literal (string "Color processed")))) (annotation - (ty-fn (effectful false) - (ty-lookup (name "RGB") (external-module "Color")) - (ty-lookup (name "Str") (builtin))))) + (declared-type + (ty-fn (effectful false) + (ty-malformed) + (ty-lookup (name "Str") (builtin)))))) (d-let (p-assign (ident "transform")) (e-closure @@ -562,7 +585,8 @@ transform = |result| (branch (patterns (pattern (degenerate false) - (p-runtime-error (tag "undeclared_type")))) + (p-nominal-external (external-module "Result") + (p-applied-tag)))) (value (e-call (e-runtime-error (tag "ident_not_in_scope")) @@ -571,19 +595,20 @@ transform = |result| (branch (patterns (pattern (degenerate false) - (p-runtime-error (tag "undeclared_type")))) + (p-nominal-external (external-module "Result") + (p-applied-tag)))) (value (e-runtime-error (tag "ident_not_in_scope"))))))))) (annotation - (ty-fn (effectful false) - (ty-apply (name "Result") (external-module "Result") - (ty-lookup (name "RGB") (external-module "Color")) - (ty-lookup (name "Error") (external-module "ExternalModule"))) - (ty-malformed)))) + (declared-type + (ty-fn (effectful false) + (ty-malformed) + (ty-malformed))))) (s-import (module "Color") (exposes)) - (s-import (module "ModuleA") - (exposes)) + (s-import (module "ModuleB") + (exposes + (exposed (name "TypeC") (wildcard false)))) (s-import (module "ExternalModule") (exposes))) ~~~ @@ -594,16 +619,16 @@ transform = |result| (patt (type "Error")) (patt (type "Error")) (patt (type "Error")) - (patt (type "Result(Num(Int(Signed32)), Str)")) + (patt (type "Error")) (patt (type "{ } -> Error")) (patt (type "Error -> Str")) - (patt (type "Result(Error, Error) -> Error"))) + (patt (type "Error -> Error"))) (expressions (expr (type "Error")) (expr (type "Error")) (expr (type "Error")) - (expr (type "Result(Num(Int(Signed32)), Str)")) + (expr (type "Error")) (expr (type "{ } -> Error")) (expr (type "Error -> Str")) - (expr (type "Result(Error, Error) -> Error")))) + (expr (type "Error -> Error")))) ~~~