From ccdefd14e2d8b4f5eeb400a725eb8abe10dc5eb8 Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Sat, 21 Dec 2024 15:58:53 -0300 Subject: [PATCH] Update to Gleam v1.5.0 (#26) * Use older version of release upload action * Fix crash * Fix go to definition for unqualified functions * Add `no-print-progress` flag to `run` and `build` * Changes! * Fix confusing `There must be a let to bind variable to value` error * Fix CI * Fix CI * Fix CI * Address review * Address review * Update changelog * Fix another compiler crash for duplicate constructor definition * Changelog * Add missing @internal * Do not create intermediate vector in `pipe.infer_each_expression` Looks like that line is no longer needed. I am not sure if compiler optimizes this or not, so why not be specific? * Fix JS generation bug * Clippy * Fix tag generation URL in docs for some VCSs * Changes! * Correct name * Use `ast` type aliases where possible * Fix CI * Refactor: use `not_in_tail_position` in `javascript/expression.rs` * Allow to omit utf8 option in literal string bit array segments * Add term printer * Implement `ValueNames` struct * Fix term printing for shadowed constructors * Tweak wording * Remove debug * Help to infer unannotated `fn` args from the call context * One more test * More tests! * Add readme note * Replace `typ` with `type_` * Use `SpannedString` alias where possible * Fix bug with code generation * Improve lambda functions inference in pipes * One more test * Update build.rs instead of using to_string, i used String::from for initial module assignment for better readability. * Update build.rs * formatting fix build.rs this might fix formatting issue. Removed the unnecessary blank line after names.sort();. After making these changes, try running cargo fmt --all -- --check again to verify that the formatting is now correct. * Improve readability * Deprecate record pattern matching syntax * Improve error message when accessing module aliases as names * Address review * Tweak error wording * Clippy * Fix function calls inference in pipes * Add a hint for a non-module-level named function * Fix lint * Add changelog entry * fix #3497 * Compiler progress in stderr * Remove unused * CHANGELOG * Correct typo in CHANGELOG.md * Fix typo in error message * Improve error message on discarded names in case patterns and assignments * Address review * feat: code action to assign `_` to unused value * add tests * chore: clean logs * chore: clean logs * update comments * rework tests * I like the new test features! * fix: only show for inner most span * add changelogs! * Fix several bit_array tests on js to expect a compilation error on supported features * Fix CI * Add a hint about placing functions into types * Fix CI * Also add a hint for `pub fn` * Tweak wording * CHANGELOG * Do not perform analysis if running main of dependency package * Add test * Address review comments * Do not load modules if skipping analysis * Review comment * CHANGELOG * Move to build tool section * Fix new line bug * Fix warning new line bug * Updates test * Removed new line complexity * chore: html sidebar module name styling * feat: add padding right and indent * fix REBAR_BARE_COMPILER_OUTPUT_DIR path Signed-off-by: Gustavo Inacio * add changelog and test Signed-off-by: Gustavo Inacio * document ezstd dep Signed-off-by: Gustavo Inacio * update ci with windows and non-windows test Signed-off-by: Gustavo Inacio * Implement code action to import modules * Change "import module" code action to read from diagnostics, Add hint to import modules when a module exists with the same name * Add hint for typos in module names * Improve code action to import modules * Address review comments * cleanup unused import * Improve completion test format * Improve error reporting for inexhaustive case expressions * Changelog * Fix comments * Address review comments * Tweak * Print correct missing patterns for inexhaustive case expressions with multiple subjects * Make errors consistent * Document errors * Improved error printing * Add file attributes * Improve stack printing * Oops, snapshots * Handle windows file attributes in test * Update panic messages * stderr * Try again! * Clippy! * Changes! * More error printing * Improve errors more * Print linked process exits nicely * Changes! * Bump wasm-bindgen from 0.2.92 to 0.2.93 Bumps [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) from 0.2.92 to 0.2.93. - [Release notes](https://github.com/rustwasm/wasm-bindgen/releases) - [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustwasm/wasm-bindgen/compare/0.2.92...0.2.93) --- updated-dependencies: - dependency-name: wasm-bindgen dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump reqwest from 0.12.5 to 0.12.7 Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.12.5 to 0.12.7. - [Release notes](https://github.com/seanmonstar/reqwest/releases) - [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md) - [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.5...v0.12.7) --- updated-dependencies: - dependency-name: reqwest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump thiserror from 1.0.59 to 1.0.63 Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.59 to 1.0.63. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.59...1.0.63) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump clap from 4.5.13 to 4.5.16 Bumps [clap](https://github.com/clap-rs/clap) from 4.5.13 to 4.5.16. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.13...clap_complete-v4.5.16) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump getrandom from 0.2.12 to 0.2.15 Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.12 to 0.2.15. - [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-random/getrandom/compare/v0.2.12...v0.2.15) --- updated-dependencies: - dependency-name: getrandom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Add code action to fill missing patterns * Improve generated code for missing case patterns code action * Improve generated code for case expressions with empty lines and no clauses * Account for case when the case expression doesn't begin the line * Clippy * Fix typo in `binaryFromSlice` type def * Fix bug for importing modules from pattern constructors * Check target support when a value is imported * Changelog * Bump quinn-proto from 0.11.3 to 0.11.8 Bumps [quinn-proto](https://github.com/quinn-rs/quinn) from 0.11.3 to 0.11.8. - [Release notes](https://github.com/quinn-rs/quinn/releases) - [Commits](https://github.com/quinn-rs/quinn/compare/quinn-proto-0.11.3...quinn-proto-0.11.8) --- updated-dependencies: - dependency-name: quinn-proto dependency-type: indirect ... Signed-off-by: dependabot[bot] * feat: better external target error * chore:add changelog * add test for unknown external target * fix clippy warnings * report unused qualified constructors * update CHANGELOG * add todo after incomplete use expression * remove additional newline from error message * Add completions for prelude values * improve error title for unknown module value * add helpful error message * Infer minimum required version * Add required_version to PackageInterface * Little fix * Add version inference tests * remove useless file * more tests! * Use version range instead of string in PackageConfiguration * add warning for gleam version range that is too permissive * refactor feature usage tracking * do not allow to publish packages with wrong version range * tests * track location of externals to provide better error message * keep track of internal annotation location * clippy! * rename field * comments * fix minimum required version * print something * clippy * CHANGELOG * switch from arc to rc for the warning emitter * Print what is changed by fix * use actual function's name and module * add external implementations to functions * fix erlang codegen for external functions * make sure to use external definitions and inline the call * rebase gone wrong * changelog * snapshot test all the things * include file names in snapshot * fix tests on windows * review comments * Report non-byte aligned bit array patterns as compile errors for JS target * make the default minimum version 0.1.0 * make sure added version constraint is >=1.x * feat: add function argument and variables suggestions * feat: add test case for function argument completion * feat: refactor code and add doc to improve clarity * fix: remove unused snapshots * feat: update changelog * fix: change visibility of method inside visitor * Fix shadowed variable suggestions * v1.5.0-rc1 * fix tuple formatting bug * CHANGELOG * Fix accessor bug Closes https://github.com/gleam-lang/gleam/issues/ * Appease Clippy * v1.5.0-rc2 * v1.5.0 * rename tests * fix enough to compile nix * fix constructor in const codegen bug same as was fixed in JS * update panic messages in Nix match new JS messages * fix binary names in CI * add missing external nix information adapt gleam#3613 to Glistix * assert nix error * some extra bit array tests still missing some * add nix to invalid target error * clippy * update flake hash * update compiler version * Fix clippy warnings for 1.83 * temp fix is_some_and * fix clippy warnings for nix * fix macos flake ci --------- Co-authored-by: Louis Pilfold Co-authored-by: GearsDatapacks Co-authored-by: Ankit Goel Co-authored-by: sobolevn Co-authored-by: Giacomo Cavalieri Co-authored-by: Manav Co-authored-by: vkobinski Co-authored-by: Paul Kuruvilla Co-authored-by: Frank Wang <1454884738@qq.com> Co-authored-by: Gustavo Inacio Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mathieu Darse Co-authored-by: Richard Viney Co-authored-by: ezegrosfeld --- .github/workflows/ci.yaml | 20 +- .github/workflows/release.yaml | 4 +- CHANGELOG.md | 463 +++++++++- Cargo.lock | 154 ++-- changelog/v1.3.md | 2 +- compiler-cli/Cargo.toml | 2 + compiler-cli/src/build.rs | 31 +- compiler-cli/src/build_lock.rs | 2 +- compiler-cli/src/cli.rs | 19 +- compiler-cli/src/compile_package.rs | 4 +- compiler-cli/src/docs.rs | 10 +- compiler-cli/src/export.rs | 14 +- compiler-cli/src/fix.rs | 77 +- compiler-cli/src/main.rs | 45 +- compiler-cli/src/publish.rs | 53 +- compiler-cli/src/run.rs | 25 +- compiler-cli/src/shell.rs | 6 +- .../templates/erlang-shipment-entrypoint.sh | 27 +- compiler-core/generated/schema_capnp.rs | 848 +++++++++++++++--- compiler-core/schema.capnp | 36 +- compiler-core/src/analyse.rs | 329 ++++--- compiler-core/src/analyse/imports.rs | 48 +- compiler-core/src/ast.rs | 49 +- compiler-core/src/ast/constant.rs | 20 +- compiler-core/src/ast/tests.rs | 42 +- compiler-core/src/ast/typed.rs | 82 +- compiler-core/src/ast/untyped.rs | 2 +- compiler-core/src/ast/visit.rs | 134 +-- compiler-core/src/ast_folder.rs | 36 +- compiler-core/src/bit_array.rs | 52 +- compiler-core/src/build.rs | 16 +- compiler-core/src/build/package_compiler.rs | 30 +- .../src/build/package_loader/tests.rs | 3 +- compiler-core/src/build/project_compiler.rs | 28 +- compiler-core/src/build/telemetry.rs | 6 + compiler-core/src/call_graph.rs | 8 +- .../call_graph/into_dependency_order_tests.rs | 2 +- compiler-core/src/config.rs | 54 +- compiler-core/src/dependency.rs | 2 +- compiler-core/src/docs.rs | 20 +- ...ts__discarded_arguments_are_not_shown.snap | 4 +- ...re_not_used_by_the_following_function.snap | 4 +- ...glistix_core__docs__tests__hello_docs.snap | 4 +- ...internal_definitions_are_not_included.snap | 4 +- ...__docs__tests__long_function_wrapping.snap | 4 +- ...code_from_function_comment_is_trimmed.snap | 4 +- ...n_code_from_module_comment_is_trimmed.snap | 4 +- ..._from_standalone_pages_is_not_trimmed.snap | 2 +- .../glistix_core__docs__tests__tables.snap | 4 +- compiler-core/src/docs/source_links.rs | 8 +- compiler-core/src/erlang.rs | 160 +++- compiler-core/src/erlang/pattern.rs | 28 +- ...erlang__tests__allowed_string_escapes.snap | 2 + ...tix_core__erlang__tests__binop_parens.snap | 2 + ...core__erlang__tests__block_assignment.snap | 2 + ...ng__tests__constant_named_module_info.snap | 2 + ...__constant_named_module_info_imported.snap | 2 + ..._named_module_info_imported_qualified.snap | 2 + ...amed_module_info_with_function_inside.snap | 3 + ...le_info_with_function_inside_imported.snap | 2 + ...th_function_inside_imported_qualified.snap | 2 + ...ore__erlang__tests__discard_in_assert.snap | 4 +- ...ng__tests__field_access_function_call.snap | 2 + ...g__tests__field_access_function_call1.snap | 2 + ...g__tests__function_argument_shadowing.snap | 2 + ...ng__tests__function_named_module_info.snap | 3 + ...__function_named_module_info_imported.snap | 2 + ..._named_module_info_imported_qualified.snap | 2 + ...unction_named_module_info_in_constant.snap | 3 + ...amed_module_info_in_constant_imported.snap | 2 + ...e_info_in_constant_imported_qualified.snap | 2 + ...lang__tests__guard_variable_rewriting.snap | 2 + ...g__tests__inline_const_pattern_option.snap | 2 + ...core__erlang__tests__integration_test.snap | 2 + ...e__erlang__tests__integration_test0_1.snap | 2 + ...e__erlang__tests__integration_test0_2.snap | 2 + ...e__erlang__tests__integration_test0_3.snap | 2 + ...ore__erlang__tests__integration_test1.snap | 2 + ...re__erlang__tests__integration_test10.snap | 2 + ...re__erlang__tests__integration_test11.snap | 2 + ...re__erlang__tests__integration_test12.snap | 2 + ...re__erlang__tests__integration_test13.snap | 3 + ...re__erlang__tests__integration_test16.snap | 3 + ...re__erlang__tests__integration_test17.snap | 2 + ...re__erlang__tests__integration_test18.snap | 2 + ...re__erlang__tests__integration_test19.snap | 2 + ...e__erlang__tests__integration_test1_1.snap | 2 + ...e__erlang__tests__integration_test1_2.snap | 2 + ...e__erlang__tests__integration_test1_4.snap | 3 + ...e__erlang__tests__integration_test1_5.snap | 3 + ...e__erlang__tests__integration_test1_6.snap | 5 + ...ore__erlang__tests__integration_test2.snap | 3 + ...re__erlang__tests__integration_test20.snap | 2 + ...re__erlang__tests__integration_test21.snap | 2 + ...re__erlang__tests__integration_test22.snap | 3 + ...re__erlang__tests__integration_test23.snap | 2 + ...ore__erlang__tests__integration_test3.snap | 2 + ...ore__erlang__tests__integration_test5.snap | 2 + ...ore__erlang__tests__integration_test6.snap | 2 + ...ore__erlang__tests__integration_test8.snap | 2 + ...ore__erlang__tests__integration_test9.snap | 2 + ...glistix_core__erlang__tests__negation.snap | 2 + ...x_core__erlang__tests__negation_block.snap | 2 + ..._tests__operator_pipe_right_hand_side.snap | 3 + ...ix_core__erlang__tests__positive_zero.snap | 2 + ...x_core__erlang__tests__recursive_type.snap | 3 + ...e__erlang__tests__scientific_notation.snap | 2 + ..._erlang__tests__tail_maybe_expr_block.snap | 2 + ..._erlang__tests__tuple_access_in_guard.snap | 2 + ..._core__erlang__tests__type_named_else.snap | 2 + ...erlang__tests__type_named_module_info.snap | 2 + ...__variable_name_underscores_preserved.snap | 2 + compiler-core/src/erlang/tests.rs | 8 +- compiler-core/src/erlang/tests/bit_arrays.rs | 45 +- ..._erlang__tests__bit_arrays__bit_array.snap | 6 +- ...erlang__tests__bit_arrays__bit_array1.snap | 3 + ...erlang__tests__bit_arrays__bit_array2.snap | 4 +- ...erlang__tests__bit_arrays__bit_array3.snap | 4 +- ...erlang__tests__bit_arrays__bit_array4.snap | 3 + ...erlang__tests__bit_arrays__bit_array5.snap | 2 + ...arrays__bit_array_declare_and_use_var.snap | 4 +- ..._tests__bit_arrays__bit_array_discard.snap | 2 + ...tests__bit_arrays__bit_array_discard1.snap | 2 + ...g__tests__bit_arrays__bit_array_float.snap | 6 +- ...al_string_constant_is_treated_as_utf8.snap | 14 + ...ray_literal_string_is_treated_as_utf8.snap | 14 + ...ral_string_pattern_is_treated_as_utf8.snap | 20 + ...sts__bit_arrays__discard_utf8_pattern.snap | 24 + ...ang__tests__bit_arrays__negative_size.snap | 2 + ...ests__bit_arrays__unicode_bit_array_1.snap | 2 + ...ests__bit_arrays__unicode_bit_array_2.snap | 2 + ...lternative_pattern_variable_rewriting.snap | 2 + ...g__tests__case__negative_zero_pattern.snap | 2 + ...listix_core__erlang__tests__case__not.snap | 2 + ...ix_core__erlang__tests__case__not_two.snap | 2 + ...g__tests__case__positive_zero_pattern.snap | 2 + ...rlang__tests__case__spread_empty_list.snap | 2 + ...ts__case__spread_empty_list_assigning.snap | 2 + ...ompilation__included_attribute_syntax.snap | 2 + ...lang__tests__consts__const_generalise.snap | 3 + ...__pub_const_equal_to_private_function.snap | 2 + ...rd_with_nested_private_function_field.snap | 2 + ...to_record_with_private_function_field.snap | 2 + ...ng__tests__consts__record_constructor.snap | 2 + ...__consts__record_constructor_in_tuple.snap | 2 + ...ests__consts__use_private_in_internal.snap | 2 + ...g__tests__consts__use_private_in_list.snap | 2 + ...__tests__consts__use_private_in_tuple.snap | 2 + ...to_record_with_private_function_field.snap | 2 + ...d_pub_const_equal_to_private_function.snap | 2 + ...to_record_with_private_function_field.snap | 2 + ..._tests__external_fn__attribute_erlang.snap | 2 + ...ts__external_fn__attribute_javascript.snap | 4 +- ...rnal_fn__both_externals_no_valid_impl.snap | 2 + ...e__erlang__tests__external_fn__elixir.snap | 2 + ...s__external_fn__erlang_and_javascript.snap | 2 + ...xternal_functions_from_another_module.snap | 2 + ...sts__external_fn__integration_test1_3.snap | 2 + ...tests__external_fn__integration_test7.snap | 3 + ...__tests__external_fn__javascript_only.snap | 2 + ...external_fn__javascript_only_indirect.snap | 2 + ...__erlang__tests__external_fn__no_body.snap | 2 + ...__erlang__tests__external_fn__private.snap | 2 + ...l_fn__private_external_function_calls.snap | 2 + ...fn__private_local_function_references.snap | 2 + ...ng__tests__external_fn__public_elixir.snap | 2 + ...ernal_fn__public_local_function_calls.snap | 3 + ...xternal_functions_from_another_module.snap | 2 + ...__tests__functions__function_as_value.snap | 3 + ...ng__tests__functions__function_called.snap | 2 + ...ed_aliased_imported_function_as_value.snap | 2 + ...sted_aliased_imported_function_called.snap | 2 + ...ns__nested_imported_function_as_value.snap | 2 + ...ions__nested_imported_function_called.snap | 2 + ...nqualified_imported_function_as_value.snap | 2 + ..._unqualified_imported_function_called.snap | 2 + ..._erlang__tests__guards__clause_guards.snap | 2 + ...rlang__tests__guards__clause_guards20.snap | 2 + ...rlang__tests__guards__clause_guards21.snap | 2 + ...rlang__tests__guards__clause_guards22.snap | 2 + ...rlang__tests__guards__clause_guards23.snap | 2 + ...rlang__tests__guards__clause_guards24.snap | 2 + ...rlang__tests__guards__clause_guards25.snap | 2 + ...rlang__tests__guards__clause_guards26.snap | 2 + ...rlang__tests__guards__clause_guards27.snap | 2 + ...rlang__tests__guards__clause_guards28.snap | 2 + ...rlang__tests__guards__clause_guards29.snap | 2 + ...rlang__tests__guards__clause_guards30.snap | 2 + ...rlang__tests__guards__clause_guards31.snap | 2 + ...rlang__tests__guards__clause_guards_1.snap | 2 + ...lang__tests__guards__clause_guards_10.snap | 2 + ...rlang__tests__guards__clause_guards_2.snap | 2 + ...rlang__tests__guards__clause_guards_3.snap | 2 + ...rlang__tests__guards__clause_guards_4.snap | 2 + ...rlang__tests__guards__clause_guards_5.snap | 2 + ...rlang__tests__guards__clause_guards_6.snap | 2 + ...rlang__tests__guards__clause_guards_7.snap | 2 + ...rlang__tests__guards__clause_guards_8.snap | 2 + ...rlang__tests__guards__clause_guards_9.snap | 2 + ...g__tests__guards__constants_in_guards.snap | 2 + ...__tests__guards__constants_in_guards1.snap | 2 + ...__erlang__tests__guards__field_access.snap | 2 + ..._erlang__tests__guards__module_access.snap | 2 + ...ng__tests__guards__module_list_access.snap | 2 + ...__tests__guards__module_nested_access.snap | 2 + ...__tests__guards__module_string_access.snap | 2 + ...g__tests__guards__module_tuple_access.snap | 2 + ...__tests__guards__nested_record_access.snap | 2 + ...e__erlang__tests__guards__only_guards.snap | 2 + ...__erlang__tests__guards__only_guards1.snap | 2 + ...__erlang__tests__guards__only_guards2.snap | 2 + ...__erlang__tests__guards__only_guards3.snap | 2 + ..._tests__let_assert__more_than_one_var.snap | 4 +- ...e__erlang__tests__let_assert__one_var.snap | 4 +- ...rlang__tests__let_assert__pattern_let.snap | 4 +- ..._tests__let_assert__variable_rewrites.snap | 6 +- ..._erlang__tests__numbers__int_negation.snap | 2 + ...ers__numbers_with_scientific_notation.snap | 2 + ...ts__numbers__numbers_with_underscores.snap | 2 + ...s__numbers__numbers_with_underscores1.snap | 2 + ...s__numbers__numbers_with_underscores2.snap | 6 +- ...tests__numbers__repeated_int_negation.snap | 2 + ...erlang__tests__numbers__zero_b_in_hex.snap | 2 + ..._core__erlang__tests__panic__panic_as.snap | 2 + ...lang__tests__panic__panic_as_function.snap | 3 + ...tix_core__erlang__tests__panic__piped.snap | 4 +- ...re__erlang__tests__panic__piped_chain.snap | 2 + ...tix_core__erlang__tests__panic__plain.snap | 4 +- ...tests__patterns__alternative_patterns.snap | 2 + ...ests__patterns__alternative_patterns1.snap | 2 + ...ests__patterns__alternative_patterns2.snap | 2 + ...ests__patterns__alternative_patterns3.snap | 2 + ...__erlang__tests__patterns__pattern_as.snap | 2 + ...ring_prefix_as_pattern_with_assertion.snap | 4 +- ...s__string_prefix_as_pattern_with_list.snap | 2 + ...fix_as_pattern_with_multiple_subjects.snap | 2 + ...tern_with_multiple_subjects_and_guard.snap | 2 + ...g__tests__pipes__block_expr_into_pipe.snap | 3 + ...g__tests__pipes__call_pipeline_result.snap | 3 + ...__tests__pipes__clever_pipe_rewriting.snap | 2 + ..._tests__pipes__clever_pipe_rewriting1.snap | 2 + ...e__erlang__tests__pipes__pipe_in_call.snap | 3 + ...g__tests__pipes__pipe_in_case_subject.snap | 2 + ...ore__erlang__tests__pipes__pipe_in_eq.snap | 3 + ...e__erlang__tests__pipes__pipe_in_list.snap | 2 + ..._erlang__tests__pipes__pipe_in_spread.snap | 3 + ...__erlang__tests__pipes__pipe_in_tuple.snap | 2 + ...alified_constructor_as_fn_name_escape.snap | 2 + ...__tests__records__pipe_update_subject.snap | 3 + ...__tests__records__record_access_block.snap | 2 + ...ds__record_accessor_multiple_variants.snap | 2 + ...multiple_variants_parameterised_types.snap | 3 + ...e_variants_positions_other_than_first.snap | 3 + ...e_with_first_position_different_types.snap | 2 + ...ang__tests__records__record_accessors.snap | 3 + ...ang__tests__records__record_constants.snap | 2 + ...erlang__tests__records__record_spread.snap | 2 + ...rlang__tests__records__record_spread1.snap | 2 + ...rlang__tests__records__record_spread2.snap | 2 + ...rlang__tests__records__record_spread3.snap | 2 + ...rlang__tests__records__record_updates.snap | 2 + ...lang__tests__records__record_updates1.snap | 2 + ...lang__tests__records__record_updates2.snap | 2 + ...lang__tests__records__record_updates3.snap | 3 + ...lang__tests__records__record_updates4.snap | 2 + ...ngs__ascii_as_unicode_escape_sequence.snap | 2 + ...__tests__strings__assert_const_concat.snap | 2 + ...ngs__assert_const_concat_many_strings.snap | 2 + ...ert_const_concat_many_strings_in_list.snap | 2 + ...ssert_const_concat_other_const_concat.snap | 2 + ..._tests__strings__assert_string_prefix.snap | 4 +- ..._strings__assert_string_prefix_discar.snap | 4 +- ..._core__erlang__tests__strings__concat.snap | 2 + ...g__tests__strings__concat_3_variables.snap | 2 + ...lang__tests__strings__concat_constant.snap | 2 + ...g__tests__strings__concat_constant_fn.snap | 3 + ..._tests__strings__concat_function_call.snap | 3 + ..._strings__discard_concat_rest_pattern.snap | 2 + ..._strings__not_unicode_escape_sequence.snap | 2 + ...strings__not_unicode_escape_sequence2.snap | 2 + ...__erlang__tests__strings__pipe_concat.snap | 3 + ...sts__strings__rest_variable_rewriting.snap | 2 + ...sts__strings__string_of_number_concat.snap | 2 + ...erlang__tests__strings__string_prefix.snap | 2 + ...ts__strings__string_prefix_assignment.snap | 2 + ...ssignment_not_unicode_escape_sequence.snap | 2 + ...efix_assignment_with_escape_sequences.snap | 2 + ...__string_prefix_assignment_with_guard.snap | 2 + ...fix_assignment_with_multiple_subjects.snap | 2 + ...ng_prefix_not_unicode_escape_sequence.snap | 2 + ...sts__strings__string_prefix_shadowing.snap | 2 + ...__string_prefix_with_escape_sequences.snap | 2 + ...ore__erlang__tests__strings__unicode1.snap | 2 + ...ore__erlang__tests__strings__unicode2.snap | 2 + ...ore__erlang__tests__strings__unicode3.snap | 2 + ...lang__tests__strings__unicode_concat1.snap | 2 + ...lang__tests__strings__unicode_concat2.snap | 2 + ...lang__tests__strings__unicode_concat3.snap | 2 + ...ngs__unicode_escape_sequence_6_digits.snap | 2 + ...stix_core__erlang__tests__todo__named.snap | 2 + ...stix_core__erlang__tests__todo__piped.snap | 2 + ...stix_core__erlang__tests__todo__plain.snap | 4 +- ...ix_core__erlang__tests__todo__todo_as.snap | 2 + ...erlang__tests__todo__todo_as_function.snap | 3 + ...ms__custom_type_named_args_count_once.snap | 4 +- ...tom_type_nested_named_args_count_once.snap | 4 +- ...om_type_nested_result_type_count_once.snap | 4 +- ...om_type_tuple_type_params_count_twice.snap | 4 +- ...params__nested_result_type_count_once.snap | 4 +- ...__type_params__result_type_count_once.snap | 4 +- ...rams__result_type_inferred_count_once.snap | 7 +- ...params__tuple_type_params_count_twice.snap | 4 +- ...ix_core__erlang__tests__use___arity_1.snap | 3 + ...ix_core__erlang__tests__use___arity_2.snap | 3 + ...ix_core__erlang__tests__use___arity_3.snap | 3 + ...erlang__tests__use___no_callback_body.snap | 4 +- ...tests__use___pipeline_that_returns_fn.snap | 3 + ...bles__anon_external_fun_name_escaping.snap | 2 + ...__tests__variables__blocks_are_scopes.snap | 2 + ...__erlang__tests__variables__discarded.snap | 2 + ...__tests__variables__module_const_vars.snap | 5 + ...ng__tests__variables__shadow_and_call.snap | 4 +- ..._erlang__tests__variables__shadow_let.snap | 2 + ...rlang__tests__variables__shadow_param.snap | 2 + ...erlang__tests__variables__shadow_pipe.snap | 4 +- compiler-core/src/error.rs | 260 ++++-- compiler-core/src/exhaustiveness.rs | 90 +- .../src/exhaustiveness/missing_patterns.rs | 112 +-- compiler-core/src/exhaustiveness/printer.rs | 546 +++++++++++ compiler-core/src/format.rs | 85 +- compiler-core/src/format/tests.rs | 2 +- compiler-core/src/format/tests/tuple.rs | 36 +- compiler-core/src/format/tests/use_.rs | 31 +- compiler-core/src/javascript.rs | 2 +- compiler-core/src/javascript/expression.rs | 183 ++-- compiler-core/src/javascript/pattern.rs | 26 +- compiler-core/src/javascript/tests.rs | 53 +- .../src/javascript/tests/bit_arrays.rs | 68 +- compiler-core/src/javascript/tests/consts.rs | 6 + .../src/javascript/tests/externals.rs | 4 +- ...avascript__tests__assignments__assert.snap | 5 +- ...vascript__tests__assignments__assert1.snap | 5 +- ...assignments__let_assert_string_prefix.snap | 5 +- ...t__tests__assignments__nested_binding.snap | 5 +- ...ssignments__returning_literal_subject.snap | 5 +- ...t__tests__assignments__tuple_matching.snap | 5 +- ...tests__assignments__variable_renaming.snap | 5 +- ...al_string_constant_is_treated_as_utf8.snap | 11 + ...ray_literal_string_is_treated_as_utf8.snap | 9 + ...ral_string_pattern_is_treated_as_utf8.snap | 14 + ..._bit_arrays_on_js_do_not_support_bits.snap | 11 + ...ipt__tests__bit_arrays__discard_sized.snap | 11 +- ...cript__tests__bit_arrays__empty_match.snap | 5 +- ..._tests__bit_arrays__match_binary_size.snap | 9 +- ...cript__tests__bit_arrays__match_bytes.snap | 5 +- ..._bit_arrays__match_dynamic_size_error.snap | 12 + ...cript__tests__bit_arrays__match_float.snap | 5 +- ..._bit_arrays__match_float_16_bit_error.snap | 12 + ...s__bit_arrays__match_float_big_endian.snap | 6 +- ...bit_arrays__match_float_little_endian.snap | 6 +- ..._tests__bit_arrays__match_float_sized.snap | 8 +- ..._arrays__match_float_sized_big_endian.snap | 6 +- ...rays__match_float_sized_little_endian.snap | 6 +- ...ys__match_non_byte_aligned_size_error.snap | 12 + ...script__tests__bit_arrays__match_rest.snap | 5 +- ...ts__bit_arrays__match_rest_deprecated.snap | 5 +- ...ript__tests__bit_arrays__match_signed.snap | 6 +- ...cript__tests__bit_arrays__match_sized.snap | 5 +- ...s__bit_arrays__match_sized_big_endian.snap | 6 +- ...arrays__match_sized_big_endian_signed.snap | 6 +- ...rays__match_sized_big_endian_unsigned.snap | 6 +- ...bit_arrays__match_sized_little_endian.snap | 6 +- ...ays__match_sized_little_endian_signed.snap | 6 +- ...s__match_sized_little_endian_unsigned.snap | 6 +- ..._tests__bit_arrays__match_sized_value.snap | 5 +- ...pt__tests__bit_arrays__match_unsigned.snap | 6 +- ...script__tests__bit_arrays__match_utf8.snap | 4 +- ...__tests__bit_arrays__not_byte_aligned.snap | 10 +- ...rays__not_byte_aligned_explicit_sized.snap | 8 +- ...__javascript__tests__bools__assigning.snap | 13 +- ...cript__tests__bools__binop_panic_left.snap | 3 +- ...ript__tests__bools__binop_panic_right.snap | 3 +- ...script__tests__bools__binop_todo_left.snap | 3 +- ...cript__tests__bools__binop_todo_right.snap | 3 +- ...avascript__tests__bools__negate_panic.snap | 3 +- ...javascript__tests__bools__negate_todo.snap | 3 +- ..._tests__bools__shadowed_bools_and_nil.snap | 13 +- ...vascript__tests__case__following_todo.snap | 3 +- ...sts__constructor_function_in_constant.snap | 8 + ...t__tests__consts__imported_aliased_ok.snap | 3 +- ...avascript__tests__consts__imported_ok.snap | 5 +- ...ructure_custom_type_with_named_fields.snap | 5 +- ...t__tests__externals__attribute_erlang.snap | 3 +- ...tests__externals__erlang_bit_patterns.snap | 8 +- ...__externals__private_attribute_erlang.snap | 3 +- ...ipt__tests__lists__list_destructuring.snap | 21 +- ...ascript__tests__numbers__int_patterns.snap | 5 +- ...mbers__preceeding_zeros_float_pattern.snap | 5 +- ...numbers__preceeding_zeros_int_pattern.snap | 5 +- ...vascript__tests__panic__as_expression.snap | 5 +- ..._core__javascript__tests__panic__bare.snap | 10 +- ..._core__javascript__tests__panic__case.snap | 2 +- ..._core__javascript__tests__panic__pipe.snap | 3 +- ...e__javascript__tests__panic__sequence.snap | 10 +- ...ript__tests__strings__string_patterns.snap | 5 +- ...ascript__tests__todo__without_message.snap | 3 +- ...script__tests__use___no_callback_body.snap | 3 +- compiler-core/src/javascript/typescript.rs | 14 +- compiler-core/src/language_server.rs | 1 + .../src/language_server/code_action.rs | 286 +++++- compiler-core/src/language_server/compiler.rs | 11 +- .../src/language_server/completer.rs | 343 +++++-- compiler-core/src/language_server/edits.rs | 78 ++ compiler-core/src/language_server/engine.rs | 99 +- compiler-core/src/language_server/progress.rs | 2 +- compiler-core/src/language_server/router.rs | 4 +- compiler-core/src/language_server/tests.rs | 31 +- .../src/language_server/tests/action.rs | 437 +++++++++ .../src/language_server/tests/completion.rs | 382 +++++++- .../src/language_server/tests/definition.rs | 683 ++++---------- .../language_server/tests/signature_help.rs | 14 +- ...ts__action__add_missing_patterns_bool.snap | 22 + ...ion__add_missing_patterns_custom_type.snap | 37 + ...action__add_missing_patterns_infinite.snap | 28 + ...__action__add_missing_patterns_inline.snap | 22 + ...ts__action__add_missing_patterns_list.snap | 29 + ...s__action__add_missing_patterns_multi.snap | 26 + ...s__action__add_missing_patterns_tuple.snap | 25 + ...__tests__action__assign_unused_result.snap | 19 + ...action__assign_unused_result_in_block.snap | 25 + ...on__assign_unused_result_on_block_end.snap | 25 + ...__assign_unused_result_on_block_start.snap | 25 + ...ssign_unused_result_only_first_action.snap | 21 + ...ction__import_module_from_constructor.snap | 18 + ...__action__import_module_from_function.snap | 18 + ...s__action__import_module_from_pattern.snap | 24 + ...ests__action__import_module_from_type.snap | 13 + ...er__tests__action__import_path_module.snap | 9 + ...ion__import_path_module_from_function.snap | 18 + ..._tests__action__import_similar_module.snap | 18 + ...s__action__rename_module_for_imported.snap | 21 + ...tests__completion__argument_shadowing.snap | 48 + ...mpletion__argument_variable_shadowing.snap | 47 + ...n__completions_for_a_const_annotation.snap | 273 +----- ...letions_for_a_function_arg_annotation.snap | 273 +----- ...ions_for_a_function_return_annotation.snap | 273 +----- ...ion__completions_for_a_var_annotation.snap | 273 +----- ...completion__completions_for_an_import.snap | 45 +- ...letions_for_an_import_from_dependency.snap | 45 +- ...r_an_import_from_dependency_with_docs.snap | 45 +- ...on__completions_for_an_import_no_test.snap | 2 +- ...for_an_import_not_from_dev_dependency.snap | 45 +- ...n_import_not_from_indirect_dependency.snap | 45 +- ...s_for_an_import_preceeding_whitespace.snap | 45 +- ...tion__completions_for_an_import_start.snap | 45 +- ...__completions_for_an_import_with_docs.snap | 45 +- ...completions_for_an_unqualified_import.snap | 219 +---- ...n_unqualified_import_already_imported.snap | 59 +- ...for_an_unqualified_import_on_new_line.snap | 107 +-- ...tion__completions_for_function_labels.snap | 194 +--- ...pletions_for_imported_function_labels.snap | 194 +--- ...ompletions_for_imported_record_labels.snap | 194 +--- ...n__completions_for_outside_a_function.snap | 2 +- ...etion__completions_for_prelude_values.snap | 37 + ...completions_for_private_record_access.snap | 52 +- ...letion__completions_for_record_access.snap | 52 +- ...letion__completions_for_record_labels.snap | 194 +--- ...ompletion__for_custom_type_definition.snap | 321 +------ ...s__completion__for_function_arguments.snap | 273 +----- ...er__tests__completion__for_type_alias.snap | 321 +------ ...import_exists_below_other_definitions.snap | 95 +- ...ble_adds_extra_new_line_if_no_imports.snap | 95 +- ...t_add_extra_new_line_if_imports_exist.snap | 95 +- ..._add_extra_new_line_if_newline_exists.snap | 95 +- ...ompletion__importable_module_function.snap | 95 +- ...able_module_function_from_deep_module.snap | 95 +- ...module_function_with_existing_imports.snap | 151 +--- ...r__tests__completion__importable_type.snap | 338 +------ ...ion__importable_type_from_deep_module.snap | 338 +------ ...importable_type_with_existing_imports.snap | 386 ++------ ...ble_type_with_existing_imports_at_top.snap | 386 ++------ ..._completion__imported_module_function.snap | 78 +- ...sts__completion__imported_public_enum.snap | 134 +-- ...s__completion__imported_public_record.snap | 78 +- ...ver__tests__completion__imported_type.snap | 321 +------ ...etion__imported_type_cursor_after_dot.snap | 321 +------ ...rsor_after_dot_other_matching_modules.snap | 321 +------ ...d_type_cursor_after_dot_other_modules.snap | 321 +------ ..._type_cursor_mid_phrase_other_modules.snap | 321 +------ ..._imported_unqualified_module_function.snap | 134 +-- ...ion__imported_unqualified_public_enum.snap | 190 +--- ...n__imported_unqualified_public_record.snap | 134 +-- ...completion__in_custom_type_definition.snap | 21 +- ...odules_from_same_package_are_included.snap | 45 +- ...l_types_from_a_dependency_are_ignored.snap | 273 +----- ...m_root_package_are_in_the_completions.snap | 369 +------- ...he_same_module_are_in_the_completions.snap | 369 +------- ..._values_from_a_dependency_are_ignored.snap | 21 +- ...m_root_package_are_in_the_completions.snap | 246 +---- ...he_same_module_are_in_the_completions.snap | 246 +---- ...tests__completion__local_private_type.snap | 321 +------ ..._tests__completion__local_public_enum.snap | 134 +-- ..._local_public_enum_with_documentation.snap | 150 +--- ...ts__completion__local_public_function.snap | 78 +- ...al_public_function_with_documentation.snap | 86 +- ...ests__completion__local_public_record.snap | 86 +- ...ocal_public_record_with_documentation.snap | 78 +- ...er__tests__completion__local_variable.snap | 56 ++ ...on__local_variable_anonymous_function.snap | 46 + ..._tests__completion__local_variable_as.snap | 54 ++ ..._completion__local_variable_bit_array.snap | 54 ++ ...etion__local_variable_case_expression.snap | 48 + ...pletion__local_variable_function_call.snap | 57 ++ ...riable_ignore_anonymous_function_args.snap | 55 ++ ...ignore_anonymous_function_args_nested.snap | 66 ++ ...le_ignore_anonymous_function_returned.snap | 65 ++ ...local_variable_ignore_within_function.snap | 10 + ...s__completion__local_variable_ignored.snap | 47 + ...n__local_variable_inside_nested_exprs.snap | 57 ++ ...al_variable_nested_anonymous_function.snap | 66 ++ ...ests__completion__local_variable_pipe.snap | 55 ++ ...letion__local_variable_pipe_with_args.snap | 64 ++ ...ts__completion__local_variable_string.snap | 46 + ...sts__completion__local_variable_tuple.snap | 70 ++ ...erver__tests__completion__opaque_type.snap | 78 +- ...__tests__completion__private_function.snap | 78 +- ...__completion__private_function_in_dep.snap | 21 +- ...rver__tests__completion__private_type.snap | 78 +- ...ests__completion__private_type_in_dep.snap | 21 +- ...completion__unqualified_imported_type.snap | 369 +------- ...tests__completion__variable_shadowing.snap | 48 + ...__goto_definition_deep_type_in_module.snap | 26 + ..._definition_external_module_constants.snap | 15 + ...nition_external_module_function_calls.snap | 15 + ...to_definition_external_module_records.snap | 19 + ...s__definition__goto_definition_import.snap | 15 + ...ition__goto_definition_import_aliased.snap | 15 + ...to_definition_import_unqualified_type.snap | 15 + ...o_definition_import_unqualified_value.snap | 15 + ..._definition_imported_module_constants.snap | 15 + ...to_definition_imported_module_records.snap | 19 + ...ition__goto_definition_local_variable.snap | 19 + ...goto_definition_module_function_calls.snap | 15 + ...n_of_external_function_in_same_module.snap | 23 + ...definition_path_module_function_calls.snap | 15 + ...goto_definition_same_module_constants.snap | 21 + ...goto_definition_same_module_functions.snap | 25 + ...__goto_definition_same_module_records.snap | 29 + ...sts__definition__goto_definition_type.snap | 27 + ...ition__goto_definition_type_in_module.snap | 19 + ...ion__goto_definition_type_in_path_dep.snap | 19 + ..._goto_definition_unqualified_function.snap | 15 + ...unqualified_imported_module_constants.snap | 15 + ...n_unqualified_imported_module_records.snap | 19 + compiler-core/src/lib.rs | 2 +- compiler-core/src/metadata/module_decoder.rs | 59 +- compiler-core/src/metadata/module_encoder.rs | 92 +- compiler-core/src/metadata/tests.rs | 178 ++-- compiler-core/src/nix.rs | 2 +- compiler-core/src/nix/expression.rs | 132 +-- compiler-core/src/nix/pattern.rs | 2 +- compiler-core/src/nix/tests.rs | 41 +- compiler-core/src/nix/tests/bit_arrays.rs | 72 +- compiler-core/src/nix/tests/consts.rs | 6 + compiler-core/src/nix/tests/externals.rs | 4 +- ...core__nix__tests__assignments__assert.snap | 5 +- ...ore__nix__tests__assignments__assert1.snap | 5 +- ...assignments__let_assert_string_prefix.snap | 5 +- ...x__tests__assignments__nested_binding.snap | 5 +- ...ssignments__returning_literal_subject.snap | 5 +- ...x__tests__assignments__tuple_matching.snap | 5 +- ...tests__assignments__variable_renaming.snap | 5 +- ...nix__tests__basic__basic_let_pat_test.snap | 25 +- ...x_core__nix__tests__basic__basic_test.snap | 11 +- ...al_string_constant_is_treated_as_utf8.snap | 11 + ...ray_literal_string_is_treated_as_utf8.snap | 13 + ...nix__tests__bit_arrays__discard_sized.snap | 5 +- ...__nix__tests__bit_arrays__empty_match.snap | 5 +- ..._tests__bit_arrays__match_binary_size.snap | 9 +- ...__nix__tests__bit_arrays__match_bytes.snap | 5 +- ..._bit_arrays__match_dynamic_size_error.snap | 12 + ..._bit_arrays__match_float_16_bit_error.snap | 12 + ...e__nix__tests__bit_arrays__match_rest.snap | 5 +- ...__nix__tests__bit_arrays__match_sized.snap | 5 +- ..._tests__bit_arrays__match_sized_value.snap | 5 +- ...__tests__bit_arrays__not_byte_aligned.snap | 9 +- ...rays__not_byte_aligned_explicit_sized.snap | 9 +- ...ix_core__nix__tests__bools__assigning.snap | 13 +- ...__nix__tests__bools__binop_panic_left.snap | 3 +- ..._nix__tests__bools__binop_panic_right.snap | 3 +- ...e__nix__tests__bools__binop_todo_left.snap | 3 +- ...__nix__tests__bools__binop_todo_right.snap | 3 +- ...core__nix__tests__bools__negate_panic.snap | 3 +- ..._core__nix__tests__bools__negate_todo.snap | 3 +- ..._tests__bools__shadowed_bools_and_nil.snap | 13 +- ...ore__nix__tests__case__following_todo.snap | 3 +- ...sts__constructor_function_in_constant.snap | 6 + ...core__nix__tests__consts__imported_ok.snap | 4 +- ...ructure_custom_type_with_named_fields.snap | 5 +- ...x__tests__externals__attribute_erlang.snap | 9 +- ...ests__externals__attribute_javascript.snap | 9 +- ...tests__externals__erlang_bit_patterns.snap | 9 +- ...__externals__private_attribute_erlang.snap | 9 +- ...ternals__private_attribute_javascript.snap | 9 +- ...nix__tests__lists__list_destructuring.snap | 21 +- ...re__nix__tests__numbers__int_patterns.snap | 5 +- ...mbers__preceeding_zeros_float_pattern.snap | 5 +- ...numbers__preceeding_zeros_int_pattern.snap | 5 +- ...ore__nix__tests__panic__as_expression.snap | 5 +- ...glistix_core__nix__tests__panic__bare.snap | 3 +- ...glistix_core__nix__tests__panic__case.snap | 3 +- ...glistix_core__nix__tests__panic__pipe.snap | 3 +- ...tix_core__nix__tests__panic__sequence.snap | 3 +- ..._nix__tests__strings__string_patterns.snap | 5 +- ...re__nix__tests__todo__without_message.snap | 9 +- ...e__nix__tests__use___no_callback_body.snap | 3 +- compiler-core/src/package_interface.rs | 6 +- compiler-core/src/package_interface/tests.rs | 6 +- compiler-core/src/parse.rs | 196 ++-- compiler-core/src/parse/error.rs | 19 +- ...re__parse__tests__const_string_concat.snap | 3 +- ..._on_variable_starting_with_underscore.snap | 12 + ...on_variable_starting_with_underscore2.snap | 12 + ..._parse__tests__function_inside_a_type.snap | 16 + ...ore__parse__tests__if_like_expression.snap | 18 + ...parse__tests__invalid_label_shorthand.snap | 6 +- ...rse__tests__invalid_label_shorthand_2.snap | 6 +- ...rse__tests__invalid_label_shorthand_3.snap | 6 +- ...rse__tests__invalid_label_shorthand_4.snap | 6 +- ...rse__tests__invalid_label_shorthand_5.snap | 6 +- ...non_module_level_function_with_a_name.snap | 13 + ...module_level_function_with_not_a_name.snap | 12 + ...se__tests__pub_function_inside_a_type.snap | 16 + ...parse__tests__unknown_external_target.snap | 12 + ...core__parse__tests__with_let_binding3.snap | 55 ++ ...sts__with_let_binding3_and_annotation.snap | 79 ++ compiler-core/src/parse/tests.rs | 107 ++- compiler-core/src/type_.rs | 133 ++- compiler-core/src/type_/environment.rs | 149 ++- compiler-core/src/type_/error.rs | 139 ++- compiler-core/src/type_/expression.rs | 412 ++++++--- compiler-core/src/type_/hydrator.rs | 16 +- compiler-core/src/type_/pattern.rs | 94 +- compiler-core/src/type_/pipe.rs | 34 +- compiler-core/src/type_/prelude.rs | 21 +- compiler-core/src/type_/pretty.rs | 24 +- compiler-core/src/type_/printer.rs | 54 +- ...us_unannotated_functions_wrong_arity1.snap | 20 + ...us_unannotated_functions_wrong_arity2.snap | 9 + ...us_unannotated_functions_wrong_arity3.snap | 18 + compiler-core/src/type_/tests.rs | 185 +++- compiler-core/src/type_/tests/accessors.rs | 26 + compiler-core/src/type_/tests/errors.rs | 81 ++ .../src/type_/tests/exhaustiveness.rs | 290 +++++- compiler-core/src/type_/tests/externals.rs | 32 +- compiler-core/src/type_/tests/functions.rs | 113 +++ compiler-core/src/type_/tests/imports.rs | 14 + compiler-core/src/type_/tests/pipes.rs | 114 ++- ..._errors__custom_type_module_constants.snap | 2 +- ...e___tests__errors__module_arity_error.snap | 5 +- ...ors__no_crash_on_duplicate_definition.snap | 14 + ...rs__no_crash_on_duplicate_definition2.snap | 14 + ...__type___tests__errors__recursive_var.snap | 5 +- ...rors__tuple_index_not_a_tuple_unbound.snap | 6 +- ...tests__errors__type_imported_as_value.snap | 2 +- ..._tests__errors__unknown_accessed_type.snap | 7 +- ...errors__unknown_module_suggest_import.snap | 12 + ...dule_suggest_typo_for_imported_module.snap | 12 + ...le_suggest_typo_for_unimported_module.snap | 12 + ...__errors__update_multi_variant_record.snap | 11 +- ...___tests__exhaustiveness__bit_array_1.snap | 5 +- ...___tests__exhaustiveness__bit_array_2.snap | 5 +- ...e___tests__exhaustiveness__bool_false.snap | 5 +- ...pe___tests__exhaustiveness__bool_true.snap | 5 +- ...rror_prints_aliased_unqualified_value.snap | 19 + ...eness__case_error_prints_module_alias.snap | 19 + ...eness__case_error_prints_module_names.snap | 20 + ...ints_module_when_aliased_and_shadowed.snap | 19 + ...ase_error_prints_module_when_shadowed.snap | 19 + ...ror_prints_prelude_module_unqualified.snap | 19 + ...r_prints_prelude_module_when_shadowed.snap | 19 + ..._error_prints_unqualifed_when_aliased.snap | 19 + ...__case_error_prints_unqualified_value.snap | 19 + ...ype___tests__exhaustiveness__custom_1.snap | 5 +- ...ype___tests__exhaustiveness__custom_2.snap | 5 +- ...pe___tests__exhaustiveness__discard_2.snap | 5 +- ...pe___tests__exhaustiveness__discard_3.snap | 5 +- ...pe___tests__exhaustiveness__discard_4.snap | 5 +- ...pe___tests__exhaustiveness__discard_5.snap | 5 +- ...pe___tests__exhaustiveness__discard_6.snap | 5 +- ...s__exhaustiveness__empty_case_of_bool.snap | 17 + ...ustiveness__empty_case_of_custom_type.snap | 18 + ...xhaustiveness__empty_case_of_external.snap | 5 +- ...__exhaustiveness__empty_case_of_float.snap | 16 + ...exhaustiveness__empty_case_of_generic.snap | 5 +- ...ts__exhaustiveness__empty_case_of_int.snap | 16 + ...s__exhaustiveness__empty_case_of_list.snap | 17 + ...tiveness__empty_case_of_multi_pattern.snap | 17 + ..._exhaustiveness__empty_case_of_string.snap | 16 + ...type___tests__exhaustiveness__float_1.snap | 5 +- ...type___tests__exhaustiveness__float_2.snap | 5 +- ...__type___tests__exhaustiveness__guard.snap | 5 +- ...type___tests__exhaustiveness__guard_1.snap | 5 +- ...stiveness__inexhaustive_multi_pattern.snap | 18 + ...tiveness__inexhaustive_multi_pattern2.snap | 20 + ...tiveness__inexhaustive_multi_pattern3.snap | 18 + ...tiveness__inexhaustive_multi_pattern4.snap | 19 + ...tiveness__inexhaustive_multi_pattern5.snap | 19 + ...__type___tests__exhaustiveness__int_1.snap | 5 +- ...__type___tests__exhaustiveness__int_2.snap | 5 +- ...type___tests__exhaustiveness__label_1.snap | 5 +- ...__type___tests__exhaustiveness__let_1.snap | 6 +- ...___tests__exhaustiveness__list_bool_1.snap | 5 +- ...___tests__exhaustiveness__list_bool_2.snap | 5 +- ...e___tests__exhaustiveness__list_empty.snap | 5 +- ...tests__exhaustiveness__list_non_empty.snap | 5 +- ...ype___tests__exhaustiveness__list_one.snap | 5 +- ...__tests__exhaustiveness__list_one_two.snap | 5 +- ...ts__exhaustiveness__list_zero_one_two.snap | 5 +- ...ts__exhaustiveness__list_zero_two_any.snap | 5 +- ...tiveness__nested_type_parameter_usage.snap | 8 +- ...exhaustiveness__reference_absent_type.snap | 5 +- ..._tests__exhaustiveness__result_bool_1.snap | 5 +- ..._tests__exhaustiveness__result_bool_2.snap | 5 +- ..._tests__exhaustiveness__result_bool_3.snap | 5 +- ..._tests__exhaustiveness__result_bool_4.snap | 5 +- ..._tests__exhaustiveness__result_bool_5.snap | 5 +- ..._tests__exhaustiveness__result_bool_6.snap | 5 +- ..._tests__exhaustiveness__result_bool_7.snap | 5 +- ..._tests__exhaustiveness__result_bool_8.snap | 5 +- ...__tests__exhaustiveness__result_error.snap | 5 +- ...sts__exhaustiveness__result_nil_error.snap | 5 +- ..._tests__exhaustiveness__result_nil_ok.snap | 5 +- ...pe___tests__exhaustiveness__result_ok.snap | 5 +- ...ype___tests__exhaustiveness__string_1.snap | 5 +- ...ype___tests__exhaustiveness__string_2.snap | 5 +- ...ype___tests__exhaustiveness__string_3.snap | 5 +- ...type___tests__exhaustiveness__tuple_0.snap | 5 +- ..._unsupported_target_for_unused_import.snap | 14 + ...rovide_arg_type_to_fn_arg_infer_error.snap | 21 + ...provide_arg_type_to_fn_explicit_error.snap | 12 + ...provide_arg_type_to_fn_implicit_error.snap | 12 + ...s__provide_arg_type_to_fn_not_a_tuple.snap | 13 + ...__provide_one_arg_type_to_two_args_fn.snap | 20 + ...ovide_two_args_type_to_fn_wrong_types.snap | 20 + ...pe___tests__functions__recursive_type.snap | 5 +- ...tests__imports__import_type_duplicate.snap | 2 +- ..._imports__module_alias_used_as_a_name.snap | 12 + ...errors_do_not_block_later_unqualified.snap | 2 +- ...__unqualified_using_opaque_constructo.snap | 2 +- ..._unqualified_using_private_constructo.snap | 2 +- ...ied_using_private_constructor_pattern.snap | 2 +- ...s__unqualified_using_private_function.snap | 2 +- ...sts__imports__using_opaque_constructo.snap | 2 +- ...ts__imports__using_private_constructo.snap | 2 +- ...ts__using_private_constructor_pattern.snap | 2 +- ...s__imports__using_private_custom_type.snap | 2 +- ..._imports__using_private_external_type.snap | 2 +- ...ests__imports__using_private_function.snap | 2 +- ...ts__imports__using_private_type_alias.snap | 2 +- ...using_private_unqualified_custom_type.snap | 2 +- ...ing_private_unqualified_external_type.snap | 2 +- ..._using_private_unqualified_type_alias.snap | 2 +- ...sts__pipes__pipe_callback_wrong_arity.snap | 9 + ...at_doesnt_take_callback_as_last_arg_2.snap | 5 +- ...nt_string_concatenation_requires_v1_4.snap | 16 + ...ngs__deprecated_record_pattern_syntax.snap | 11 + ...d_pattern_syntax_with_label_shorthand.snap | 11 + ..._record_pattern_syntax_with_no_labels.snap | 11 + ..._float_divide_in_guards_requires_v1_3.snap | 16 + ...__float_minus_in_guards_requires_v1_3.snap | 16 + ...ultiplication_in_guards_requires_v1_3.snap | 16 + ...s__float_plus_in_guards_requires_v1_3.snap | 16 + ...s__int_divide_in_guards_requires_v1_3.snap | 16 + ...gs__int_minus_in_guards_requires_v1_3.snap | 16 + ...ultiplication_in_guards_requires_v1_3.snap | 16 + ...ngs__int_plus_in_guards_requires_v1_3.snap | 16 + ...int_remainder_in_guards_requires_v1_3.snap | 16 + ..._annotation_on_constant_requires_v1_1.snap | 16 + ..._annotation_on_function_requires_v1_1.snap | 16 + ...rnal_annotation_on_type_requires_v1_1.snap | 16 + ...external_module_with_at_requires_v1_2.snap | 17 + ...label_shorthand_in_call_requires_v1_4.snap | 16 + ...l_shorthand_in_constand_requires_v1_4.snap | 16 + ...el_shorthand_in_pattern_requires_v1_4.snap | 16 + ..._array_constant_segment_requires_v1_5.snap | 17 + ...t_array_pattern_segment_requires_v1_5.snap | 17 + ...on_in_bit_array_segment_requires_v1_5.snap | 17 + ...gs__nested_tuple_access_requires_v1_1.snap | 17 + ...ngs__unused_module_select_constructor.snap | 9 + ...nding_with_variant_raises_a_warning_2.snap | 9 + .../src/type_/tests/target_implementations.rs | 7 + .../src/type_/tests/version_inference.rs | 315 +++++++ compiler-core/src/type_/tests/warnings.rs | 409 ++++++++- compiler-core/src/version.rs | 2 +- compiler-core/src/warning.rs | 110 ++- compiler-core/templates/docs-css/index.css | 8 + .../templates/documentation_layout.html | 4 +- compiler-core/templates/gleam@@main.erl | 98 +- compiler-core/templates/prelude.d.mts | 2 +- compiler-core/templates/prelude.mjs | 21 +- compiler-wasm/src/lib.rs | 4 +- compiler-wasm/src/log_telemetry.rs | 16 + docs/runtime-errors.md | 67 ++ nix/glistix.nix | 2 +- test-package-compiler/build.rs | 8 +- test-package-compiler/src/generated_tests.rs | 145 ++- test-package-compiler/src/lib.rs | 23 +- ...rated_tests__alias_unqualified_import.snap | 3 + ..._generated_tests__erlang_escape_names.snap | 6 + ...piler__generated_tests__erlang_import.snap | 2 + ...ests__erlang_import_shadowing_prelude.snap | 2 + ...piler__generated_tests__erlang_nested.snap | 2 + ..._compiler__generated_tests__hello_joe.snap | 2 + ...d_tests__import_shadowed_name_warning.snap | 5 +- ...__generated_tests__imported_constants.snap | 11 + ...enerated_tests__imported_external_fns.snap | 11 + ...d_tests__imported_record_constructors.snap | 18 + ...erated_tests__opaque_type_destructure.snap | 2 +- ...sts__unknown_module_field_in_constant.snap | 4 +- ...s__unknown_module_field_in_expression.snap | 4 +- ...tests__unknown_module_field_in_import.snap | 4 +- ...__generated_tests__variable_or_module.snap | 4 + .../src/external_only_erlang.gleam | 10 +- .../src/external_only_javascript.gleam | 10 +- test/project_erlang/gleam.toml | 3 + test/project_erlang/manifest.toml | 2 + .../.gitignore | 4 + .../README.md | 7 + .../gleam.toml | 20 + .../manifest.toml | 13 + ...ackage_not_compiled_when_running_dep.gleam | 3 + .../test.sh | 34 + 833 files changed, 15525 insertions(+), 12147 deletions(-) create mode 100644 compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap create mode 100644 compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap create mode 100644 compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_pattern_is_treated_as_utf8.snap create mode 100644 compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__discard_utf8_pattern.snap create mode 100644 compiler-core/src/exhaustiveness/printer.rs create mode 100644 compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap create mode 100644 compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap create mode 100644 compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_pattern_is_treated_as_utf8.snap create mode 100644 compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_arrays_on_js_do_not_support_bits.snap create mode 100644 compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_dynamic_size_error.snap create mode 100644 compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_16_bit_error.snap create mode 100644 compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_non_byte_aligned_size_error.snap create mode 100644 compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__constructor_function_in_constant.snap create mode 100644 compiler-core/src/language_server/edits.rs create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_bool.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_custom_type.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_infinite.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_inline.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_list.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_multi.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_tuple.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_in_block.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_on_block_end.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_on_block_start.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_only_first_action.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_constructor.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_function.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_pattern.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_type.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_path_module.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_path_module_from_function.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_similar_module.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__rename_module_for_imported.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__argument_shadowing.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__argument_variable_shadowing.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_prelude_values.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_anonymous_function.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_as.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_bit_array.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_case_expression.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_function_call.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_args.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_args_nested.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_returned.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_within_function.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignored.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_inside_nested_exprs.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_nested_anonymous_function.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_pipe.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_pipe_with_args.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_string.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_tuple.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__variable_shadowing.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_constants.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_records.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_aliased.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_imported_module_constants.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_imported_module_records.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_local_variable.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_module_function_calls.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_of_external_function_in_same_module.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_constants.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_functions.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_records.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type_in_module.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_function.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap create mode 100644 compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap create mode 100644 compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap create mode 100644 compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_dynamic_size_error.snap create mode 100644 compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_float_16_bit_error.snap create mode 100644 compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__consts__constructor_function_in_constant.snap create mode 100644 compiler-core/src/parse/snapshots/glistix_core__parse__tests__error_message_on_variable_starting_with_underscore.snap create mode 100644 compiler-core/src/parse/snapshots/glistix_core__parse__tests__error_message_on_variable_starting_with_underscore2.snap create mode 100644 compiler-core/src/parse/snapshots/glistix_core__parse__tests__function_inside_a_type.snap create mode 100644 compiler-core/src/parse/snapshots/glistix_core__parse__tests__if_like_expression.snap create mode 100644 compiler-core/src/parse/snapshots/glistix_core__parse__tests__non_module_level_function_with_a_name.snap create mode 100644 compiler-core/src/parse/snapshots/glistix_core__parse__tests__non_module_level_function_with_not_a_name.snap create mode 100644 compiler-core/src/parse/snapshots/glistix_core__parse__tests__pub_function_inside_a_type.snap create mode 100644 compiler-core/src/parse/snapshots/glistix_core__parse__tests__unknown_external_target.snap create mode 100644 compiler-core/src/parse/snapshots/glistix_core__parse__tests__with_let_binding3.snap create mode 100644 compiler-core/src/parse/snapshots/glistix_core__parse__tests__with_let_binding3_and_annotation.snap create mode 100644 compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity1.snap create mode 100644 compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity2.snap create mode 100644 compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity3.snap create mode 100644 compiler-core/src/type_/tests/accessors.rs create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__no_crash_on_duplicate_definition.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__no_crash_on_duplicate_definition2.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_import.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_typo_for_imported_module.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_typo_for_unimported_module.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_aliased_unqualified_value.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_alias.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_names.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_when_aliased_and_shadowed.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_when_shadowed.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_prelude_module_unqualified.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_prelude_module_when_shadowed.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_unqualifed_when_aliased.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_unqualified_value.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_bool.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_custom_type.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_float.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_int.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_list.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_multi_pattern.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_string.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern2.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern3.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern4.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern5.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__externals__unsupported_target_for_unused_import.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_arg_infer_error.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_explicit_error.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_implicit_error.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_not_a_tuple.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_one_arg_type_to_two_args_fn.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_two_args_type_to_fn_wrong_types.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__module_alias_used_as_a_name.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__pipes__pipe_callback_wrong_arity.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__constant_string_concatenation_requires_v1_4.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax_with_label_shorthand.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax_with_no_labels.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_divide_in_guards_requires_v1_3.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_minus_in_guards_requires_v1_3.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_multiplication_in_guards_requires_v1_3.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_plus_in_guards_requires_v1_3.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_divide_in_guards_requires_v1_3.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_minus_in_guards_requires_v1_3.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_multiplication_in_guards_requires_v1_3.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_plus_in_guards_requires_v1_3.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_remainder_in_guards_requires_v1_3.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_constant_requires_v1_1.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_function_requires_v1_1.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_type_requires_v1_1.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__javascript_external_module_with_at_requires_v1_2.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_call_requires_v1_4.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_constand_requires_v1_4.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_pattern_requires_v1_4.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_constant_segment_requires_v1_5.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_pattern_segment_requires_v1_5.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_segment_requires_v1_5.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__nested_tuple_access_requires_v1_1.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__unused_module_select_constructor.snap create mode 100644 compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__unused_pipeline_ending_with_variant_raises_a_warning_2.snap create mode 100644 compiler-core/src/type_/tests/version_inference.rs create mode 100644 docs/runtime-errors.md create mode 100644 test/root_package_not_compiled_when_running_dep/.gitignore create mode 100644 test/root_package_not_compiled_when_running_dep/README.md create mode 100644 test/root_package_not_compiled_when_running_dep/gleam.toml create mode 100644 test/root_package_not_compiled_when_running_dep/manifest.toml create mode 100644 test/root_package_not_compiled_when_running_dep/src/root_package_not_compiled_when_running_dep.gleam create mode 100755 test/root_package_not_compiled_when_running_dep/test.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bc71fbcf1..a0ed639f6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -167,12 +167,19 @@ jobs: working-directory: ./test/project_erlang_windows if: ${{ runner.os == 'Windows' && matrix.run-integration-tests }} - - name: test/project_erlang export package-interface + - name: test/project_erlang export package-interface (non-windows) run: | glistix export package-interface --out="interface.json" cat interface.json working-directory: ./test/project_erlang - if: ${{ matrix.run-integration-tests }} + if: ${{ runner.os != 'Windows' && matrix.run-integration-tests }} + + - name: test/project_erlang export package-interface (windows) + run: | + glistix export package-interface --out="interface.json" + cat interface.json + working-directory: ./test/project_erlang_windows + if: ${{ runner.os == 'Windows' && matrix.run-integration-tests }} - name: test/external_only_javascript run: ./test.sh @@ -188,6 +195,13 @@ jobs: env: GLEAM_COMMAND: glistix + - name: test/root_package_not_compiled_when_running_dep + run: ./test.sh + working-directory: ./test/root_package_not_compiled_when_running_dep + if: ${{ matrix.run-integration-tests }} + env: + GLEAM_COMMAND: glistix + - name: test/project_javascript run: | glistix run @@ -365,7 +379,7 @@ jobs: target: aarch64-unknown-linux-gnu - os: ubuntu-latest target: aarch64-unknown-linux-musl - - os: macos-12 # intel + - os: macos-13 # intel (macos-14 only supports aarch64) target: x86_64-apple-darwin - os: macos-14 # aarch64 target: aarch64-apple-darwin diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e3201d326..ef59a0812 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -100,7 +100,9 @@ jobs: esac - name: Upload release archive - uses: softprops/action-gh-release@v2 + # https://github.com/softprops/action-gh-release/issues/445 + # uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@0bd7e8b279c9b5b36661d552472fbbfe671fe26e with: draft: true prerelease: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 792a76044..475038a76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,478 @@ # Gleam's Changelog -## Unreleased +## v1.5.0 - 2024-09-19 + +## v1.5.0-rc2 - 2024-09-18 + +### Bug Fixes + +- Fixed a bug where the formatter would not format nested tuple access properly. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- Fixed a bug where multi-variant custom type accessors wouldn't be properly + detected. + ([Louis Pilfold](https://github.com/lpil)) + + +## v1.5.0-rc1 - 2024-09-14 ### Build tool +- The `--no-print-progress` flag has been added to prevent the build tool from + printing messages as the project is built. + ([Ankit Goel](https://github.com/crazymerlyn)) + +- The compiler is now able to run a dependency's module using `gleam run -m` + even when there's compilation errors in your own project's code. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- HTML docs: make module names in sidebar wrap before a / when possible + ([Jiangda Wang](https://github.com/frank-iii)) + +- The printing of runtime errors has been improved, including those from linked + processes. + ([Louis Pilfold](https://github.com/lpil)) + +- OTP application trees are now shut down gracefully when `main` exits. + ([Louis Pilfold](https://github.com/lpil)) + +- The `gleam fix` command can now update a project's `gleam` version contraint + to make sure it respects the inferred minimum required version. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- The build tool now refuses to publish a project where the `gleam` version + constraint would include a compiler version that doesn't support the features + used by the package. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- If a project doesn't specify a `gleam` version constraint, the build tool will + automatically infer it and add it to the project's `gleam.toml` before + publishing it. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + ### Compiler +- Compiler progress is now printed to stderr, instead of stdout. + ([Victor Kobinski](https://github.com/vkobinski)) + +- It is now possible to omit the `:utf8` option for literal strings used in a + `BitArray` segment. + + ```gleam + <<"Hello", " ", "world">> + ``` + + Is the same as: + + ```gleam + <<"Hello":utf8, " ":utf8, "world":utf8>> + ``` + + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- In inexhaustive pattern match errors the missing variants are now printed + using the correct syntax for the module the error is emitted in, rather than + the module it was defined in. For example, if you had this code: + + ```gleam + import gleam/option + + pub fn main() { + let an_option = option.Some("wibble!") + case an_option { + option.None -> "missing" + } + } + ``` + + The error message would show the qualified `option.Some(_)` as the missing + pattern: + + ```txt + error: Inexhaustive patterns + ┌─ /Users/giacomocavalieri/Desktop/prova/src/prova.gleam:5:3 + │ + 5 │ ╭ case an_option { + 6 │ │ option.None -> "missing" + 7 │ │ } + │ ╰───^ + + This case expression does not have a pattern for all possible values. If it + is run on one of the values without a pattern then it will crash. + + The missing patterns are: + + option.Some(_) + ``` + + ([Surya Rose](https://github.com/gearsdatapacks)) + +- Anonymous functions that are immediately called with a record or a tuple as an + argument are now inferred correctly without the need to add type annotations. + For example you can now write: + + ```gleam + fn(x) { x.0 }(#(1, 2)) + // ^ you no longer need to annotate this! + ``` + + ([sobolevn](https://github.com/sobolevn)) + +- Anonymous functions that are being piped a record or a tuple as an argument + are now inferred correctly without the need to add type annotations. For + example you can now write: + + ```gleam + pub type User { + User(name: String) + } + + pub fn main() { + User("Giacomo") + |> fn(user) { user.name } + // ^^^^ you no longer need to annotate this! + |> io.debug + } + ``` + + ([sobolevn](https://github.com/sobolevn)) + +- The record pattern matching syntax `Record(a ..)` is now deprecated in favour + of the `Record(a, ..)` syntax. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- Adds a better error message when module names are used as values. For example + the following code: + + ```gleam + import gleam/list + + pub fn main() { + list + } + ``` + + Results in the error: + + ```txt + error: Module `list` used as a value + ┌─ /Users/giacomocavalieri/Desktop/prova/src/prova.gleam:4:3 + │ + 4 │ list + │ ^^^^ + + Modules are not values, so you cannot assign them to variables, pass them to + functions, or anything else that you would do with a value. + ``` + + ([sobolevn](https://github.com/sobolevn)) + +- An helpful error message has been added when the programmer attempts to write + a function within a custom type definition, likely trying to declare an OOP + class. For example: + + ```gleam + pub type User { + User(name: String) + + fn greet(user: User) -> String { + "hello " <> user.name + } + } + ``` + + Now results in the following error: + + ```txt + error: Syntax error + ┌─ /Users/giacomocavalieri/Desktop/prova/src/prova.gleam:8:3 + │ + 8 │ fn greet(user: User) -> String { + │ ^^ I was not expecting this + + Found the keyword `fn`, expected one of: + - `}` + - a record constructor + Hint: Gleam is not an object oriented programming language so + functions are declared separately from types. + ``` + + ([sobolevn](https://github.com/sobolevn)) + +- The compiler now gives a hint to import a module when accessing modules that + aren't imported. It only suggests a module if it exports a type/value with + the same name as what the user was trying to access: + + ```gleam + pub fn main() { + io.println("Hello, world!") + } + ``` + + Produces the following error: + + ``` + error: Unknown module + ┌─ /src/file.gleam:2:3 + │ + 2 │ io.println("Hello, world!") + │ ^^ + + No module has been found with the name `io`. + Hint: Did you mean to import `gleam/io`? + ``` + + This code, however, produces no hint: + + ```gleam + pub fn main() { + io.non_existent() + } + ``` + + ([Surya Rose](https://github.com/gearsdatapacks)) + +- The compiler now provides improved suggestions in the error for an + inexhaustive case expression. The following code: + + ```gleam + let a = True + case a {} + ``` + + Now produces this error: + + ``` + error: Inexhaustive patterns + ┌─ /src/file.gleam:3:3 + │ + 3 │ case a {} + │ ^^^^^^^^^ + + This case expression does not have a pattern for all possible values. If it + is run on one of the values without a pattern then it will crash. + + The missing patterns are: + + False + True + ``` + + Whereas before, it would suggest `_` as the only missing pattern. + ([Surya Rose](https://github.com/GearsDatapacks)) + +- Improve error message for using `@external` with unknown target + ([Jiangda Wang](https://github.com/frank-iii)) + +- Improved error title when using an unknown module value. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- The compiler now shows an helpful error message if you try writing an `if` + expression instead of a case. For example, this code: + + ```gleam + pub fn main() { + let a = if wibble { + 1 + } + } + ``` + + Results in the following error: + + ```txt + error: Syntax error + ┌─ /src/parse/error.gleam:3:11 + │ + 3 │ let a = if wibble { + │ ^^ Gleam doesn't have if expressions + + If you want to write a conditional expression you can use a `case`: + + case condition { + True -> todo + False -> todo + } + + See: https://tour.gleam.run/flow-control/case-expressions/ + ``` + + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- The compiler can now infer the minimum Gleam version needed for your code to + compile and emits a warning if the project's `gleam` version constraint + doesn't include it. + For example, let's say your `gleam.toml` has the constraint + `gleam = ">= 1.1.0"` and your code is using some feature introduced in a later + version: + + ```gleam + // Concatenating constant strings was introduced in v1.4.0! + pub const greeting = "hello " <> "world!" + ``` + + You would now get the following warning: + + ```txt + warning: Incompatible gleam version range + ┌─ /Users/giacomocavalieri/Desktop/datalog/src/datalog.gleam:1:22 + │ + 1 │ pub const greeting = "hello " <> "world!" + │ ^^^^^^^^^^^^^^^^^^^^ This requires a Gleam version >= 1.4.0 + + Constant strings concatenation was introduced in version v1.4.0. But the + Gleam version range specified in your `gleam.toml` would allow this code to + run on an earlier version like v1.1.0, resulting in compilation errors! + Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.4.0" + ``` + + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- On the JavaScript target, non-byte aligned integers in bit array patterns are + now reported as a compile-time error. + + ([Richard Viney](https://github.com/richard-viney)) + ### Formatter +- The formatter now adds a `todo` after a `use` expression if it is the last + expression in a block. For example, the following code: + + ```gleam + pub fn main() { + use user <- result.try(fetch_user()) + } + ``` + + Is rewritten as: + + ```gleam + pub fn main() { + use user <- result.try(fetch_user()) + todo + } + ``` + + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + ### Language Server +- The language server can now show completions for local variables inside a function. + ([Ezekiel Grosfeld](https://github.com/ezegros)) + +- The language server can now suggest a code action to assign an unused value to + `_`. + ([Jiangda Wang](https://github.com/frank-iii)) + +- The language server can now suggest a code action to import modules for + existing code which references unimported modules: + + ```gleam + pub fn main() { + io.println("Hello, world!") + } + ``` + + Becomes: + + ```gleam + import gleam/io + + pub fn main() { + io.println("Hello, world!") + } + ``` + + ([Surya Rose](https://github.com/gearsdatapacks)) + +- The Language Server can now suggest a code action to fill in the missing + patterns of a case expression: + + ```gleam + let a = True + case a {} + ``` + + Becomes: + + ```gleam + let a = True + case a { + False -> todo + True -> todo + } + ``` + + ([Surya Rose](https://github.com/GearsDatapacks)) + ### Bug Fixes +- Fixed a bug where the warnings were printed above the errors without any new + line between them. + ([Victor Kobinski](https://github.com/vkobinski)) + +- Fixed a bug which caused the language server and compiler to crash when two + constructors of the same name were created. + ([Surya Rose](https://github.com/GearsDatapacks)) + +- Fixed a bug where jumping to the definition of an unqualified function would + produce the correct location, but remain in the same file. + ([Surya Rose](https://github.com/gearsdatapacks)) + +- Fixed a bug where incorrect syntax error message were shown, when using `:` or + `=` in wrong positions in expressions. + ([Ankit Goel](https://github.com/crazymerlyn)) + +- Fixed a bug where the compiler would crash when pattern matching on a type + which had constructors of duplicate names. + ([Surya Rose](https://github.com/gearsdatapacks)) + +- Fixed a bug where referencing record constructors in JavaScript constants but + not calling them could produce invalid code. + ([Louis Pilfold](https://github.com/lpil)) + +- Fixed a bug where source links in HTML documentation would be incorrect for + Codeberg, SourceHut, and Gitea. + ([sobolevn](https://github.com/sobolevn)) + +- Fixed a bug with Erlang code generation for discard utf8 patterns in bit + arrays. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- Fixed a bug which affected inference of function calls in pipe expressions. + ([sobolevn](https://github.com/sobolevn)) + +- Improved an error message when using variable names starting with an + underscore in expression like: `let some = _func()` or `case { 1 -> _func() }` + ([sobolevn](https://github.com/sobolevn)) + +- Fixed a bug where the provided `REBAR_BARE_COMPILER_OUTPUT_DIR` env var would + use relative path instead of absolute path causing compilation errors in some + packages. + ([Gustavo Inacio](https://github.com/gusinacio)) + +- Fixed a bug where the compiler would print incorrect missing patterns for + inexhaustive case expressions matching on more than one subject. + ([Surya Rose](https://github.com/GearsDatapacks)) + +- Fixed a bug where the compiler would not check the target support of a + function if it was imported and not used, and generate invalid code. + ([Surya Rose](https://github.com/GearsDatapacks)) + +- Fixed a bug where an qualified unused constructor wouldn't be reported as + unused. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- The Language Server now correctly shows completions for values in the Gleam + prelude. + ([Surya Rose](https://github.com/GearsDatapacks)) + +- Fixed a bug where the language server wouldn't let you jump to the definition + of a function with an external implementation defined in the same module. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + ## v1.4.1 - 2024-08-04 ### Bug Fixes diff --git a/Cargo.lock b/Cargo.lock index 93a70b93b..7b49a4753 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" @@ -329,9 +329,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "clap" -version = "4.5.13" +version = "4.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" dependencies = [ "clap_builder", "clap_derive", @@ -339,9 +339,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.13" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstream", "anstyle", @@ -774,9 +774,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -818,6 +818,7 @@ dependencies = [ "lsp-types", "opener", "pretty_assertions", + "pubgrub", "regex", "reqwest", "rpassword", @@ -1810,9 +1811,9 @@ checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ "base64 0.22.0", "bytes", @@ -1847,7 +1848,7 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "webpki-roots", - "winreg", + "windows-registry", ] [[package]] @@ -2208,6 +2209,9 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "synstructure" @@ -2291,18 +2295,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", @@ -2647,11 +2651,12 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "serde", "serde_json", "wasm-bindgen-macro", @@ -2659,9 +2664,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", @@ -2686,9 +2691,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2696,9 +2701,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", @@ -2709,9 +2714,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wasm-bindgen-test" @@ -2807,7 +2812,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -2816,7 +2821,37 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", ] [[package]] @@ -2834,7 +2869,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -2854,17 +2889,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2875,9 +2911,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2887,9 +2923,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2899,9 +2935,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -2911,9 +2953,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2923,9 +2965,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2935,9 +2977,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2947,9 +2989,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -2960,16 +3002,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "x509-parser" version = "0.15.1" diff --git a/changelog/v1.3.md b/changelog/v1.3.md index e26d2feec..8804d0697 100644 --- a/changelog/v1.3.md +++ b/changelog/v1.3.md @@ -91,7 +91,7 @@ Unsupported feature for Javascript since they would already cause a runtime error on Javascript. - This means if you compile specifically for Javascript you will now recieve + This means if you compile specifically for Javascript you will now receive this error: ``` diff --git a/compiler-cli/Cargo.toml b/compiler-cli/Cargo.toml index 8d0a59870..c543c57b3 100644 --- a/compiler-cli/Cargo.toml +++ b/compiler-cli/Cargo.toml @@ -35,6 +35,8 @@ fslock = "0" same-file = "1" # Open generated docs in browser opener = "0" +# Pubgrub dependency resolution algorithm +pubgrub = "0" camino = { workspace = true, features = ["serde1"] } async-trait.workspace = true base16.workspace = true diff --git a/compiler-cli/src/build.rs b/compiler-cli/src/build.rs index 7c4a45bcf..a747ad720 100644 --- a/compiler-cli/src/build.rs +++ b/compiler-cli/src/build.rs @@ -1,9 +1,10 @@ -use std::{sync::Arc, time::Instant}; +use std::{rc::Rc, time::Instant}; use glistix_core::{ - build::{Built, Codegen, Options, ProjectCompiler}, + build::{Built, Codegen, NullTelemetry, Options, ProjectCompiler, Telemetry}, manifest::Manifest, paths::ProjectPaths, + warning::WarningEmitterIO, Result, }; @@ -14,16 +15,28 @@ use crate::{ fs::{self, get_current_directory, get_project_root, ConsoleWarningEmitter}, }; -pub fn download_dependencies() -> Result { +pub fn download_dependencies(telemetry: impl Telemetry) -> Result { let paths = crate::find_project_paths()?; - crate::dependencies::download(&paths, cli::Reporter::new(), None, UseManifest::Yes) + crate::dependencies::download(&paths, telemetry, None, UseManifest::Yes) } pub fn main(options: Options, manifest: Manifest) -> Result { + main_with_warnings(options, manifest, Rc::new(ConsoleWarningEmitter)) +} + +pub(crate) fn main_with_warnings( + options: Options, + manifest: Manifest, + warnings: Rc, +) -> Result { let paths = crate::find_project_paths()?; let perform_codegen = options.codegen; let root_config = crate::config::root_config()?; - let telemetry = Box::new(cli::Reporter::new()); + let telemetry: &'static dyn Telemetry = if options.no_print_progress { + &NullTelemetry + } else { + &cli::Reporter + }; let io = fs::ProjectIO::new(); let start = Instant::now(); let lock = BuildLock::new_target( @@ -35,13 +48,13 @@ pub fn main(options: Options, manifest: Manifest) -> Result { tracing::info!("Compiling packages"); let result = { - let _guard = lock.lock(telemetry.as_ref()); + let _guard = lock.lock(telemetry); let compiler = ProjectCompiler::new( root_config, options, manifest.packages, telemetry, - Arc::new(ConsoleWarningEmitter), + warnings, ProjectPaths::new(current_dir), io, ); @@ -49,8 +62,8 @@ pub fn main(options: Options, manifest: Manifest) -> Result { }; match perform_codegen { - Codegen::All | Codegen::DepsOnly => cli::print_compiled(start.elapsed()), - Codegen::None => cli::print_checked(start.elapsed()), + Codegen::All | Codegen::DepsOnly => telemetry.compiled_package(start.elapsed()), + Codegen::None => telemetry.checked_package(start.elapsed()), }; Ok(result) diff --git a/compiler-cli/src/build_lock.rs b/compiler-cli/src/build_lock.rs index 0c612ffae..998a41513 100644 --- a/compiler-cli/src/build_lock.rs +++ b/compiler-cli/src/build_lock.rs @@ -29,7 +29,7 @@ impl BuildLock { } /// Lock the specified directory - pub fn lock(&self, telemetry: &Telem) -> Result { + pub fn lock(&self, telemetry: &Telem) -> Result { tracing::debug!(path=?self.directory, "locking_build_directory"); crate::fs::mkdir(&self.directory)?; diff --git a/compiler-cli/src/cli.rs b/compiler-cli/src/cli.rs index 04cc93e54..95aca0e43 100644 --- a/compiler-cli/src/cli.rs +++ b/compiler-cli/src/cli.rs @@ -19,10 +19,18 @@ impl Reporter { } impl Telemetry for Reporter { + fn compiled_package(&self, duration: Duration) { + print_compiled(duration); + } + fn compiling_package(&self, name: &str) { print_compiling(name); } + fn checked_package(&self, duration: Duration) { + print_checked(duration); + } + fn checking_package(&self, name: &str) { print_checking(name); } @@ -39,6 +47,10 @@ impl Telemetry for Reporter { print_resolving_versions() } + fn running(&self, name: &str) { + print_running(name); + } + fn waiting_for_build_directory_lock(&self) { print_waiting_for_build_directory_lock() } @@ -157,7 +169,7 @@ pub fn seconds(duration: Duration) -> String { } pub fn print_colourful_prefix(prefix: &str, text: &str) { - let buffer_writer = stdout_buffer_writer(); + let buffer_writer = stderr_buffer_writer(); let mut buffer = buffer_writer.buffer(); buffer .set_color( @@ -179,11 +191,6 @@ pub fn stderr_buffer_writer() -> BufferWriter { BufferWriter::stderr(color_choice()) } -pub fn stdout_buffer_writer() -> BufferWriter { - // Don't add color codes to the output if standard error isn't connected to a terminal - BufferWriter::stdout(color_choice()) -} - fn colour_forced() -> bool { if let Ok(force) = std::env::var("FORCE_COLOR") { !force.is_empty() diff --git a/compiler-cli/src/compile_package.rs b/compiler-cli/src/compile_package.rs index 5f6e51e0c..c397d3c6b 100644 --- a/compiler-cli/src/compile_package.rs +++ b/compiler-cli/src/compile_package.rs @@ -16,13 +16,13 @@ use glistix_core::{ warning::WarningEmitter, Error, Result, }; -use std::{collections::HashSet, sync::Arc}; +use std::{collections::HashSet, rc::Rc}; pub fn command(options: CompilePackage) -> Result<()> { let ids = UniqueIdGenerator::new(); let mut type_manifests = load_libraries(&ids, &options.libraries_directory)?; let mut defined_modules = im::HashMap::new(); - let warnings = WarningEmitter::new(Arc::new(ConsoleWarningEmitter)); + let warnings = WarningEmitter::new(Rc::new(ConsoleWarningEmitter)); let paths = ProjectPaths::new(options.package_directory.clone()); let config = config::read(paths.root_config())?; diff --git a/compiler-cli/src/docs.rs b/compiler-cli/src/docs.rs index 5a636fabb..5de1946b3 100644 --- a/compiler-cli/src/docs.rs +++ b/compiler-cli/src/docs.rs @@ -5,7 +5,7 @@ use camino::{Utf8Path, Utf8PathBuf}; use crate::{cli, fs::ProjectIO, hex::ApiKeyCommand, http::HttpClient}; use glistix_core::{ analyse::TargetSupport, - build::{Codegen, Mode, Options, Package, Target}, + build::{Codegen, Compile, Mode, Options, Package, Target}, config::{DocsPage, PackageConfig}, docs::DocContext, error::Error, @@ -73,10 +73,12 @@ pub fn build(options: BuildOptions) -> Result<()> { mode: Mode::Prod, target: options.target, codegen: Codegen::All, + compile: Compile::All, warnings_as_errors: false, root_target_support: TargetSupport::Enforced, + no_print_progress: false, }, - crate::build::download_dependencies()?, + crate::build::download_dependencies(cli::Reporter::new())?, )?; let outputs = build_documentation(&config, &mut built.root_package, DocContext::Build)?; @@ -166,10 +168,12 @@ impl PublishCommand { root_target_support: TargetSupport::Enforced, warnings_as_errors: false, codegen: Codegen::All, + compile: Compile::All, mode: Mode::Prod, target: None, + no_print_progress: false, }, - crate::build::download_dependencies()?, + crate::build::download_dependencies(cli::Reporter::new())?, )?; let outputs = build_documentation(&config, &mut built.root_package, DocContext::HexPublish)?; diff --git a/compiler-cli/src/export.rs b/compiler-cli/src/export.rs index 4f533d57b..e5e44049f 100644 --- a/compiler-cli/src/export.rs +++ b/compiler-cli/src/export.rs @@ -1,7 +1,7 @@ use camino::Utf8PathBuf; use glistix_core::{ analyse::TargetSupport, - build::{Codegen, Mode, Options, Target}, + build::{Codegen, Compile, Mode, Options, Target}, Result, }; @@ -45,10 +45,12 @@ pub(crate) fn erlang_shipment() -> Result<()> { root_target_support: TargetSupport::Enforced, warnings_as_errors: false, codegen: Codegen::All, + compile: Compile::All, mode, target: Some(target), + no_print_progress: false, }, - crate::build::download_dependencies()?, + crate::build::download_dependencies(crate::cli::Reporter::new())?, )?; for entry in crate::fs::read_dir(&build)?.filter_map(Result::ok) { @@ -103,8 +105,8 @@ the {file} script. pub fn hex_tarball() -> Result<()> { let paths = crate::find_project_paths()?; - let config = crate::config::root_config()?; - let data: Vec = crate::publish::build_hex_tarball(&paths, &config)?; + let mut config = crate::config::root_config()?; + let data: Vec = crate::publish::build_hex_tarball(&paths, &mut config)?; let path = paths.build_export_hex_tarball(&config.name, &config.version.to_string()); crate::fs::write_bytes(&path, &data)?; @@ -139,10 +141,12 @@ pub fn package_interface(path: Utf8PathBuf) -> Result<()> { mode: Mode::Prod, target: None, codegen: Codegen::All, + compile: Compile::All, warnings_as_errors: false, root_target_support: TargetSupport::Enforced, + no_print_progress: false, }, - crate::build::download_dependencies()?, + crate::build::download_dependencies(crate::cli::Reporter::new())?, )?; built.root_package.attach_doc_and_module_comments(); diff --git a/compiler-cli/src/fix.rs b/compiler-cli/src/fix.rs index 05ca192da..7c414d128 100644 --- a/compiler-cli/src/fix.rs +++ b/compiler-cli/src/fix.rs @@ -1,13 +1,48 @@ +use std::rc::Rc; + use camino::{Utf8Path, Utf8PathBuf}; use glistix_core::{ + analyse::TargetSupport, + build::{Codegen, Compile, Mode, Options}, error::{FileIoAction, FileKind}, - Error, Result, + type_, + warning::VectorWarningEmitterIO, + Error, Result, Warning, }; +use hexpm::version::Version; + +use crate::{build, cli}; pub fn run() -> Result<()> { - for path in crate::fs::gleam_files_excluding_gitignore(Utf8Path::new(".")) { - fix_file(path)?; - } + // When running gleam fix we want all the compilation warnings to be hidden, + // at the same time we need to access those to apply the fixes: so we + // accumulate those into a vector. + let warnings = Rc::new(VectorWarningEmitterIO::new()); + let _built = build::main_with_warnings( + Options { + root_target_support: TargetSupport::Enforced, + warnings_as_errors: false, + codegen: Codegen::DepsOnly, + compile: Compile::All, + mode: Mode::Dev, + target: None, + no_print_progress: false, + }, + build::download_dependencies(cli::Reporter::new())?, + warnings.clone(), + )?; + let warnings = warnings.take(); + + fix_minimum_required_version(warnings)?; + + println!("Done!"); + Ok(()) +} + +fn fix_minimum_required_version(warnings: Vec) -> Result<()> { + let Some(minimum_required_version) = minimum_required_version_from_warnings(warnings) else { + return Ok(()); + }; // Set the version requirement in gleam.toml let mut toml = crate::fs::read("gleam.toml")? @@ -21,25 +56,33 @@ pub fn run() -> Result<()> { #[allow(clippy::indexing_slicing)] { - toml["gleam"] = toml_edit::value(">= 0.32.0"); + toml["gleam"] = toml_edit::value(format!(">= {minimum_required_version}")); } // Write the updated config crate::fs::write(Utf8Path::new("gleam.toml"), &toml.to_string())?; - println!( - "Your Gleam code has been fixed! - -If you have any JavaScript code that used the BitString class -you will need to update it to use the BitArray class instead. -" - ); + println!("- Set required Gleam version to \">= {minimum_required_version}\""); Ok(()) } -fn fix_file(path: Utf8PathBuf) -> Result<()> { - let src = crate::fs::read(&path)?; - let out = glistix_core::fix::parse_fix_and_format(&src.into(), &path)?; - crate::fs::write(&path, &out)?; - Ok(()) +/// Returns the highest minimum required version among all warnings requiring a +/// specific Gleam version that is not allowed by the `gleam` version contraint +/// in the `gleam.toml`. +fn minimum_required_version_from_warnings(warnings: Vec) -> Option { + warnings + .iter() + .filter_map(|warning| match warning { + Warning::Type { + warning: + type_::Warning::FeatureRequiresHigherGleamVersion { + minimum_required_version, + .. + }, + .. + } => Some(minimum_required_version), + _ => None, + }) + .reduce(std::cmp::max) + .cloned() } diff --git a/compiler-cli/src/main.rs b/compiler-cli/src/main.rs index d487a5aab..8c148fef0 100644 --- a/compiler-cli/src/main.rs +++ b/compiler-cli/src/main.rs @@ -77,7 +77,7 @@ pub use glistix_core::error::{Error, Result}; use glistix_core::{ analyse::TargetSupport, - build::{Codegen, Mode, Options, Runtime, Target}, + build::{Codegen, Compile, Mode, NullTelemetry, Options, Runtime, Target}, hex::RetirementReason, paths::ProjectPaths, version::COMPILER_VERSION, @@ -108,7 +108,6 @@ use strum::VariantNames; .usage(styling::AnsiColor::Yellow.on_default()) .literal(styling::AnsiColor::Green.on_default()) )] - enum Command { /// Build the project Build { @@ -118,6 +117,10 @@ enum Command { #[arg(short, long, ignore_case = true, help = target_doc())] target: Option, + + /// Don't print progress information + #[clap(long)] + no_print_progress: bool, }, /// Type check the project @@ -192,6 +195,10 @@ enum Command { #[arg(short, long)] module: Option, + /// Don't print progress information + #[clap(long)] + no_print_progress: bool, + arguments: Vec, }, @@ -446,7 +453,8 @@ fn main() { Command::Build { target, warnings_as_errors, - } => command_build(target, warnings_as_errors), + no_print_progress, + } => command_build(target, warnings_as_errors, no_print_progress), Command::Check { target } => command_check(target), @@ -481,13 +489,21 @@ fn main() { arguments, runtime, module, - } => run::command(arguments, target, runtime, module, run::Which::Src), + no_print_progress, + } => run::command( + arguments, + target, + runtime, + module, + run::Which::Src, + no_print_progress, + ), Command::Test { target, arguments, runtime, - } => run::command(arguments, target, runtime, None, run::Which::Test), + } => run::command(arguments, target, runtime, None, run::Which::Test, false), Command::CompilePackage(opts) => compile_package::command(opts), @@ -548,24 +564,37 @@ fn command_check(target: Option) -> Result<()> { root_target_support: TargetSupport::Enforced, warnings_as_errors: false, codegen: Codegen::DepsOnly, + compile: Compile::All, mode: Mode::Dev, target, + no_print_progress: false, }, - build::download_dependencies()?, + build::download_dependencies(cli::Reporter::new())?, )?; Ok(()) } -fn command_build(target: Option, warnings_as_errors: bool) -> Result<()> { +fn command_build( + target: Option, + warnings_as_errors: bool, + no_print_progress: bool, +) -> Result<()> { + let manifest = if no_print_progress { + build::download_dependencies(NullTelemetry)? + } else { + build::download_dependencies(cli::Reporter::new())? + }; let _ = build::main( Options { root_target_support: TargetSupport::Enforced, warnings_as_errors, codegen: Codegen::All, + compile: Compile::All, mode: Mode::Dev, target, + no_print_progress, }, - build::download_dependencies()?, + manifest, )?; Ok(()) } diff --git a/compiler-cli/src/publish.rs b/compiler-cli/src/publish.rs index 356625c74..32604a150 100644 --- a/compiler-cli/src/publish.rs +++ b/compiler-cli/src/publish.rs @@ -2,9 +2,10 @@ use camino::{Utf8Path, Utf8PathBuf}; use flate2::{write::GzEncoder, Compression}; use glistix_core::{ analyse::TargetSupport, - build::{Codegen, Mode, Options, Package, Target}, + build::{Codegen, Compile, Mode, Options, Package, Target}, config::{PackageConfig, SpdxLicense}, docs::DocContext, + error::SmallVersion, hex, paths::{self, ProjectPaths}, requirement::Requirement, @@ -36,7 +37,7 @@ pub struct PublishCommand { impl PublishCommand { pub fn setup(replace: bool, i_am_sure: bool) -> Result> { let paths = crate::find_project_paths()?; - let config = crate::config::root_config()?; + let mut config = crate::config::root_config()?; let should_publish = check_for_gleam_prefix(&config, i_am_sure)? && check_for_version_zero(&config, i_am_sure)? @@ -52,7 +53,7 @@ impl PublishCommand { data: package_tarball, src_files_added, generated_files_added, - } = do_build_hex_tarball(&paths, &config)?; + } = do_build_hex_tarball(&paths, &mut config)?; check_for_name_squatting(&compile_result)?; @@ -242,12 +243,12 @@ struct Tarball { generated_files_added: Vec<(Utf8PathBuf, String)>, } -pub fn build_hex_tarball(paths: &ProjectPaths, config: &PackageConfig) -> Result> { +pub fn build_hex_tarball(paths: &ProjectPaths, config: &mut PackageConfig) -> Result> { let Tarball { data, .. } = do_build_hex_tarball(paths, config)?; Ok(data) } -fn do_build_hex_tarball(paths: &ProjectPaths, config: &PackageConfig) -> Result { +fn do_build_hex_tarball(paths: &ProjectPaths, config: &mut PackageConfig) -> Result { let target = config.target; check_config_for_publishing(config)?; @@ -262,10 +263,46 @@ fn do_build_hex_tarball(paths: &ProjectPaths, config: &PackageConfig) -> Result< mode: Mode::Prod, target: Some(target), codegen: Codegen::All, + compile: Compile::All, + no_print_progress: false, }, - build::download_dependencies()?, + build::download_dependencies(cli::Reporter::new())?, )?; + let minimum_required_version = built.minimum_required_version(); + match &config.gleam_version { + // If the package has no explicit `gleam` version in its `gleam.toml` + // then we want to add the automatically inferred one so we know it's + // correct and folks getting the package from Hex won't have unpleasant + // surprises if the author forgot to manualy write it down. + None => { + // If we're automatically adding the minimum required version + // constraint we want it to at least be `>= 1.0.0`, even if the + // inferred lower bound could be lower. + let minimum_required_version = + std::cmp::max(minimum_required_version, Version::new(1, 0, 0)); + let inferred_version_range = + pubgrub::range::Range::higher_than(minimum_required_version); + config.gleam_version = Some(inferred_version_range); + } + // Otherwise we need to check that the annotated version range is + // correct and includes the minimum required version. + Some(gleam_version) => { + if let Some(lowest_allowed_version) = gleam_version.lowest_version() { + if lowest_allowed_version < minimum_required_version { + return Err(Error::CannotPublishWrongVersion { + minimum_required_version: SmallVersion::from_hexpm( + minimum_required_version, + ), + wrongfully_allowed_version: SmallVersion::from_hexpm( + lowest_allowed_version, + ), + }); + } + } + } + } + // If any of the modules in the package contain a todo then refuse to // publish as the package is not yet finished. let unfinished = built @@ -532,7 +569,7 @@ pub struct ReleaseMetadata<'a> { // extra: (kvlist(string => kvlist(...))) (optional) } -impl<'a> ReleaseMetadata<'a> { +impl ReleaseMetadata<'_> { pub fn as_erlang(&self) -> String { fn link(link: &(&str, http::Uri)) -> String { format!( @@ -589,7 +626,7 @@ struct ReleaseRequirement<'a> { // Support alternate repositories at a later date. // repository: String, } -impl<'a> ReleaseRequirement<'a> { +impl ReleaseRequirement<'_> { pub fn as_erlang(&self) -> String { format!( r#" diff --git a/compiler-cli/src/run.rs b/compiler-cli/src/run.rs index 7db7dca7f..fc1892f6b 100644 --- a/compiler-cli/src/run.rs +++ b/compiler-cli/src/run.rs @@ -4,7 +4,7 @@ use camino::Utf8PathBuf; use ecow::EcoString; use glistix_core::{ analyse::TargetSupport, - build::{Built, Codegen, Mode, Options, Runtime, Target}, + build::{Built, Codegen, Compile, Mode, NullTelemetry, Options, Runtime, Target, Telemetry}, config::{DenoFlag, PackageConfig}, error::Error, io::{CommandExecutor, Stdio}, @@ -27,6 +27,7 @@ pub fn command( runtime: Option, module: Option, which: Which, + no_print_progress: bool, ) -> Result<(), Error> { let paths = crate::find_project_paths()?; @@ -39,8 +40,18 @@ pub fn command( } }; + let telemetry: &'static dyn Telemetry = if no_print_progress { + &NullTelemetry + } else { + &crate::cli::Reporter + }; + // Download dependencies - let manifest = crate::build::download_dependencies()?; + let manifest = if no_print_progress { + crate::build::download_dependencies(NullTelemetry)? + } else { + crate::build::download_dependencies(crate::cli::Reporter::new())? + }; // Get the config for the module that is being run to check the target. // Also get the kind of the package the module belongs to: wether the module @@ -65,6 +76,13 @@ pub fn command( let options = Options { warnings_as_errors: false, + compile: match package_kind { + // If we're trying to run a dependecy module we do not compile and + // check the root package. So we can run the main function from a + // dependency's module even if the root package doesn't compile. + PackageKind::Dependency => Compile::DepsOnly, + PackageKind::Root => Compile::All, + }, codegen: Codegen::All, mode: Mode::Dev, target: Some(target), @@ -76,6 +94,7 @@ pub fn command( // only care if the dependency can compile for the current target. PackageKind::Dependency => TargetSupport::NotEnforced, }, + no_print_progress, }; let built = crate::build::main(options, manifest)?; @@ -86,7 +105,7 @@ pub fn command( // Don't exit on ctrl+c as it is used by child erlang shell ctrlc::set_handler(move || {}).expect("Error setting Ctrl-C handler"); - crate::cli::print_running(&format!("{module}.main")); + telemetry.running(&format!("{module}.main")); // Run the command let status = match target { diff --git a/compiler-cli/src/shell.rs b/compiler-cli/src/shell.rs index 8be73979e..d4d30399b 100644 --- a/compiler-cli/src/shell.rs +++ b/compiler-cli/src/shell.rs @@ -1,6 +1,6 @@ use glistix_core::{ analyse::TargetSupport, - build::{Codegen, Mode, Options, Target}, + build::{Codegen, Compile, Mode, Options, Target}, error::Error, }; use std::process::Command; @@ -14,10 +14,12 @@ pub fn command() -> Result<(), Error> { root_target_support: TargetSupport::Enforced, warnings_as_errors: false, codegen: Codegen::All, + compile: Compile::All, mode: Mode::Dev, target: Some(Target::Erlang), + no_print_progress: false, }, - crate::build::download_dependencies()?, + crate::build::download_dependencies(crate::cli::Reporter::new())?, )?; // Don't exit on ctrl+c as it is used by child erlang shell diff --git a/compiler-cli/templates/erlang-shipment-entrypoint.sh b/compiler-cli/templates/erlang-shipment-entrypoint.sh index 67698b56f..4c3da9cc3 100644 --- a/compiler-cli/templates/erlang-shipment-entrypoint.sh +++ b/compiler-cli/templates/erlang-shipment-entrypoint.sh @@ -18,21 +18,22 @@ shell() { } case "$COMMAND" in - run) - shift - run "$@" +run) + shift + run "$@" ;; - shell) - shell +shell) + shell ;; - *) - echo "usage:" >&2 - echo " entrypoint.sh \$COMMAND" >&2 - echo "" >&2 - echo "commands:" >&2 - echo " run Run the project main function" >&2 - echo " shell Run an Erlang shell" >&2 - exit 1 +*) + echo "usage:" >&2 + echo " entrypoint.sh \$COMMAND" >&2 + echo "" >&2 + echo "commands:" >&2 + echo " run Run the project main function" >&2 + echo " shell Run an Erlang shell" >&2 + exit 1 + ;; esac diff --git a/compiler-core/generated/schema_capnp.rs b/compiler-core/generated/schema_capnp.rs index 288c43d2e..a7796ca81 100644 --- a/compiler-core/generated/schema_capnp.rs +++ b/compiler-core/generated/schema_capnp.rs @@ -470,32 +470,32 @@ pub mod module { !self.reader.get_pointer_field(5).is_null() } #[inline] - pub fn get_unused_imports(self) -> ::capnp::Result<::capnp::struct_list::Reader<'a,crate::schema_capnp::src_span::Owned>> { + pub fn get_line_numbers(self) -> ::capnp::Result> { ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(6), ::core::option::Option::None) } #[inline] - pub fn has_unused_imports(&self) -> bool { + pub fn has_line_numbers(&self) -> bool { !self.reader.get_pointer_field(6).is_null() } #[inline] - pub fn get_line_numbers(self) -> ::capnp::Result> { + pub fn get_src_path(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(7), ::core::option::Option::None) } #[inline] - pub fn has_line_numbers(&self) -> bool { + pub fn has_src_path(&self) -> bool { !self.reader.get_pointer_field(7).is_null() } #[inline] - pub fn get_src_path(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { - ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(8), ::core::option::Option::None) + pub fn get_is_internal(self) -> bool { + self.reader.get_bool_field(0) } #[inline] - pub fn has_src_path(&self) -> bool { - !self.reader.get_pointer_field(8).is_null() + pub fn get_required_version(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(8), ::core::option::Option::None) } #[inline] - pub fn get_is_internal(self) -> bool { - self.reader.get_bool_field(0) + pub fn has_required_version(&self) -> bool { + !self.reader.get_pointer_field(8).is_null() } } @@ -644,60 +644,60 @@ pub mod module { !self.builder.get_pointer_field(5).is_null() } #[inline] - pub fn get_unused_imports(self) -> ::capnp::Result<::capnp::struct_list::Builder<'a,crate::schema_capnp::src_span::Owned>> { + pub fn get_line_numbers(self) -> ::capnp::Result> { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(6), ::core::option::Option::None) } #[inline] - pub fn set_unused_imports(&mut self, value: ::capnp::struct_list::Reader<'a,crate::schema_capnp::src_span::Owned>) -> ::capnp::Result<()> { + pub fn set_line_numbers(&mut self, value: crate::schema_capnp::line_numbers::Reader<'_>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(6), value, false) } #[inline] - pub fn init_unused_imports(self, size: u32) -> ::capnp::struct_list::Builder<'a,crate::schema_capnp::src_span::Owned> { - ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(6), size) + pub fn init_line_numbers(self, ) -> crate::schema_capnp::line_numbers::Builder<'a> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(6), 0) } #[inline] - pub fn has_unused_imports(&self) -> bool { + pub fn has_line_numbers(&self) -> bool { !self.builder.get_pointer_field(6).is_null() } #[inline] - pub fn get_line_numbers(self) -> ::capnp::Result> { + pub fn get_src_path(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(7), ::core::option::Option::None) } #[inline] - pub fn set_line_numbers(&mut self, value: crate::schema_capnp::line_numbers::Reader<'_>) -> ::capnp::Result<()> { - ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(7), value, false) + pub fn set_src_path(&mut self, value: ::capnp::text::Reader<'_>) { + self.builder.get_pointer_field(7).set_text(value); } #[inline] - pub fn init_line_numbers(self, ) -> crate::schema_capnp::line_numbers::Builder<'a> { - ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(7), 0) + pub fn init_src_path(self, size: u32) -> ::capnp::text::Builder<'a> { + self.builder.get_pointer_field(7).init_text(size) } #[inline] - pub fn has_line_numbers(&self) -> bool { + pub fn has_src_path(&self) -> bool { !self.builder.get_pointer_field(7).is_null() } #[inline] - pub fn get_src_path(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { - ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(8), ::core::option::Option::None) + pub fn get_is_internal(self) -> bool { + self.builder.get_bool_field(0) } #[inline] - pub fn set_src_path(&mut self, value: ::capnp::text::Reader<'_>) { - self.builder.get_pointer_field(8).set_text(value); + pub fn set_is_internal(&mut self, value: bool) { + self.builder.set_bool_field(0, value); } #[inline] - pub fn init_src_path(self, size: u32) -> ::capnp::text::Builder<'a> { - self.builder.get_pointer_field(8).init_text(size) + pub fn get_required_version(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(8), ::core::option::Option::None) } #[inline] - pub fn has_src_path(&self) -> bool { - !self.builder.get_pointer_field(8).is_null() + pub fn set_required_version(&mut self, value: crate::schema_capnp::version::Reader<'_>) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(8), value, false) } #[inline] - pub fn get_is_internal(self) -> bool { - self.builder.get_bool_field(0) + pub fn init_required_version(self, ) -> crate::schema_capnp::version::Builder<'a> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(8), 0) } #[inline] - pub fn set_is_internal(&mut self, value: bool) { - self.builder.set_bool_field(0, value); + pub fn has_required_version(&self) -> bool { + !self.builder.get_pointer_field(8).is_null() } } @@ -709,7 +709,10 @@ pub mod module { } impl Pipeline { pub fn get_line_numbers(&self) -> crate::schema_capnp::line_numbers::Pipeline { - ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(7)) + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(6)) + } + pub fn get_required_version(&self) -> crate::schema_capnp::version::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(8)) } } mod _private { @@ -719,6 +722,155 @@ pub mod module { } } +pub mod version { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl <'a> ::capnp::traits::Owned<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; } + impl <'a> ::capnp::traits::OwnedStruct<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + #[derive(Clone, Copy)] + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,> ::capnp::traits::FromStructReader<'a> for Reader<'a,> { + fn new(reader: ::capnp::private::layout::StructReader<'a>) -> Reader<'a,> { + Reader { reader, } + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result> { + ::core::result::Result::Ok(::capnp::traits::FromStructReader::new(reader.get_struct(default)?)) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Reader { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_major(self) -> u32 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_minor(self) -> u32 { + self.reader.get_data_field::(1) + } + #[inline] + pub fn get_patch(self) -> u32 { + self.reader.get_data_field::(2) + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + #[inline] + fn struct_size() -> ::capnp::private::layout::StructSize { _private::STRUCT_SIZE } + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,> ::capnp::traits::FromStructBuilder<'a> for Builder<'a,> { + fn new(builder: ::capnp::private::layout::StructBuilder<'a>) -> Builder<'a, > { + Builder { builder, } + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Builder<'a,> { + ::capnp::traits::FromStructBuilder::new(builder.init_struct(_private::STRUCT_SIZE)) + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result> { + ::core::result::Result::Ok(::capnp::traits::FromStructBuilder::new(builder.get_struct(_private::STRUCT_SIZE, default)?)) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder<'b>(pointer: ::capnp::private::layout::PointerBuilder<'b>, value: Reader<'a,>, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { .. *self } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.into_reader().total_size() + } + #[inline] + pub fn get_major(self) -> u32 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_major(&mut self, value: u32) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_minor(self) -> u32 { + self.builder.get_data_field::(1) + } + #[inline] + pub fn set_minor(&mut self, value: u32) { + self.builder.set_data_field::(1, value); + } + #[inline] + pub fn get_patch(self) -> u32 { + self.builder.get_data_field::(2) + } + #[inline] + pub fn set_patch(&mut self, value: u32) { + self.builder.set_data_field::(2, value); + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Pipeline { + Pipeline { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + use capnp::private::layout; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 2, pointers: 0 }; + pub const TYPE_ID: u64 = 0xfc86_6c3f_4528_fa9c; + } +} + pub mod types_variant_constructors { #[derive(Copy, Clone)] pub struct Owned(()); @@ -1252,32 +1404,36 @@ pub mod type_constructor { !self.reader.get_pointer_field(2).is_null() } #[inline] - pub fn get_publicity(self) -> ::core::result::Result { - ::capnp::traits::FromU16::from_u16(self.reader.get_data_field::(0)) + pub fn get_publicity(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(3), ::core::option::Option::None) + } + #[inline] + pub fn has_publicity(&self) -> bool { + !self.reader.get_pointer_field(3).is_null() } #[inline] pub fn get_deprecated(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { - ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(3), ::core::option::Option::None) + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(4), ::core::option::Option::None) } #[inline] pub fn has_deprecated(&self) -> bool { - !self.reader.get_pointer_field(3).is_null() + !self.reader.get_pointer_field(4).is_null() } #[inline] pub fn get_origin(self) -> ::capnp::Result> { - ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(4), ::core::option::Option::None) + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(5), ::core::option::Option::None) } #[inline] pub fn has_origin(&self) -> bool { - !self.reader.get_pointer_field(4).is_null() + !self.reader.get_pointer_field(5).is_null() } #[inline] pub fn get_documentation(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { - ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(5), ::core::option::Option::None) + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(6), ::core::option::Option::None) } #[inline] pub fn has_documentation(&self) -> bool { - !self.reader.get_pointer_field(5).is_null() + !self.reader.get_pointer_field(6).is_null() } } @@ -1378,60 +1534,68 @@ pub mod type_constructor { !self.builder.get_pointer_field(2).is_null() } #[inline] - pub fn get_publicity(self) -> ::core::result::Result { - ::capnp::traits::FromU16::from_u16(self.builder.get_data_field::(0)) + pub fn get_publicity(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(3), ::core::option::Option::None) } #[inline] - pub fn set_publicity(&mut self, value: crate::schema_capnp::Publicity) { - self.builder.set_data_field::(0, value as u16) + pub fn set_publicity(&mut self, value: crate::schema_capnp::publicity::Reader<'_>) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(3), value, false) + } + #[inline] + pub fn init_publicity(self, ) -> crate::schema_capnp::publicity::Builder<'a> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(3), 0) + } + #[inline] + pub fn has_publicity(&self) -> bool { + !self.builder.get_pointer_field(3).is_null() } #[inline] pub fn get_deprecated(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { - ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(3), ::core::option::Option::None) + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(4), ::core::option::Option::None) } #[inline] pub fn set_deprecated(&mut self, value: ::capnp::text::Reader<'_>) { - self.builder.get_pointer_field(3).set_text(value); + self.builder.get_pointer_field(4).set_text(value); } #[inline] pub fn init_deprecated(self, size: u32) -> ::capnp::text::Builder<'a> { - self.builder.get_pointer_field(3).init_text(size) + self.builder.get_pointer_field(4).init_text(size) } #[inline] pub fn has_deprecated(&self) -> bool { - !self.builder.get_pointer_field(3).is_null() + !self.builder.get_pointer_field(4).is_null() } #[inline] pub fn get_origin(self) -> ::capnp::Result> { - ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(4), ::core::option::Option::None) + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(5), ::core::option::Option::None) } #[inline] pub fn set_origin(&mut self, value: crate::schema_capnp::src_span::Reader<'_>) -> ::capnp::Result<()> { - ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(4), value, false) + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(5), value, false) } #[inline] pub fn init_origin(self, ) -> crate::schema_capnp::src_span::Builder<'a> { - ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(4), 0) + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(5), 0) } #[inline] pub fn has_origin(&self) -> bool { - !self.builder.get_pointer_field(4).is_null() + !self.builder.get_pointer_field(5).is_null() } #[inline] pub fn get_documentation(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { - ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(5), ::core::option::Option::None) + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(6), ::core::option::Option::None) } #[inline] pub fn set_documentation(&mut self, value: ::capnp::text::Reader<'_>) { - self.builder.get_pointer_field(5).set_text(value); + self.builder.get_pointer_field(6).set_text(value); } #[inline] pub fn init_documentation(self, size: u32) -> ::capnp::text::Builder<'a> { - self.builder.get_pointer_field(5).init_text(size) + self.builder.get_pointer_field(6).init_text(size) } #[inline] pub fn has_documentation(&self) -> bool { - !self.builder.get_pointer_field(5).is_null() + !self.builder.get_pointer_field(6).is_null() } } @@ -1445,13 +1609,16 @@ pub mod type_constructor { pub fn get_type(&self) -> crate::schema_capnp::type_::Pipeline { ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(0)) } + pub fn get_publicity(&self) -> crate::schema_capnp::publicity::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(3)) + } pub fn get_origin(&self) -> crate::schema_capnp::src_span::Pipeline { - ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(4)) + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(5)) } } mod _private { use capnp::private::layout; - pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 6 }; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 0, pointers: 7 }; pub const TYPE_ID: u64 = 0xb1fb_6d62_e00b_6d7a; } } @@ -2697,16 +2864,20 @@ pub mod value_constructor { !self.reader.get_pointer_field(1).is_null() } #[inline] - pub fn get_publicity(self) -> ::core::result::Result { - ::capnp::traits::FromU16::from_u16(self.reader.get_data_field::(0)) + pub fn get_publicity(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(2), ::core::option::Option::None) + } + #[inline] + pub fn has_publicity(&self) -> bool { + !self.reader.get_pointer_field(2).is_null() } #[inline] pub fn get_deprecated(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { - ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(2), ::core::option::Option::None) + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(3), ::core::option::Option::None) } #[inline] pub fn has_deprecated(&self) -> bool { - !self.reader.get_pointer_field(2).is_null() + !self.reader.get_pointer_field(3).is_null() } } @@ -2791,28 +2962,230 @@ pub mod value_constructor { !self.builder.get_pointer_field(1).is_null() } #[inline] - pub fn get_publicity(self) -> ::core::result::Result { - ::capnp::traits::FromU16::from_u16(self.builder.get_data_field::(0)) + pub fn get_publicity(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(2), ::core::option::Option::None) + } + #[inline] + pub fn set_publicity(&mut self, value: crate::schema_capnp::publicity::Reader<'_>) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(2), value, false) + } + #[inline] + pub fn init_publicity(self, ) -> crate::schema_capnp::publicity::Builder<'a> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(2), 0) + } + #[inline] + pub fn has_publicity(&self) -> bool { + !self.builder.get_pointer_field(2).is_null() + } + #[inline] + pub fn get_deprecated(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(3), ::core::option::Option::None) + } + #[inline] + pub fn set_deprecated(&mut self, value: ::capnp::text::Reader<'_>) { + self.builder.get_pointer_field(3).set_text(value); + } + #[inline] + pub fn init_deprecated(self, size: u32) -> ::capnp::text::Builder<'a> { + self.builder.get_pointer_field(3).init_text(size) + } + #[inline] + pub fn has_deprecated(&self) -> bool { + !self.builder.get_pointer_field(3).is_null() + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Pipeline { + Pipeline { _typeless: typeless, } + } + } + impl Pipeline { + pub fn get_type(&self) -> crate::schema_capnp::type_::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(0)) + } + pub fn get_variant(&self) -> crate::schema_capnp::value_constructor_variant::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(1)) + } + pub fn get_publicity(&self) -> crate::schema_capnp::publicity::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(2)) + } + } + mod _private { + use capnp::private::layout; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 0, pointers: 4 }; + pub const TYPE_ID: u64 = 0xd4c6_d8f1_a8fb_051c; + } +} + +pub mod publicity { + pub use self::Which::{Public,Private,Internal}; + + #[derive(Copy, Clone)] + pub struct Owned(()); + impl <'a> ::capnp::traits::Owned<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; } + impl <'a> ::capnp::traits::OwnedStruct<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + #[derive(Clone, Copy)] + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,> ::capnp::traits::FromStructReader<'a> for Reader<'a,> { + fn new(reader: ::capnp::private::layout::StructReader<'a>) -> Reader<'a,> { + Reader { reader, } + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result> { + ::core::result::Result::Ok(::capnp::traits::FromStructReader::new(reader.get_struct(default)?)) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Reader { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn has_internal(&self) -> bool { + if self.reader.get_data_field::(0) != 2 { return false; } + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn which(self) -> ::core::result::Result, ::capnp::NotInSchema> { + match self.reader.get_data_field::(0) { + 0 => { + ::core::result::Result::Ok(Public( + () + )) + } + 1 => { + ::core::result::Result::Ok(Private( + () + )) + } + 2 => { + ::core::result::Result::Ok(Internal( + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + )) + } + x => ::core::result::Result::Err(::capnp::NotInSchema(x)) + } + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + #[inline] + fn struct_size() -> ::capnp::private::layout::StructSize { _private::STRUCT_SIZE } + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,> ::capnp::traits::FromStructBuilder<'a> for Builder<'a,> { + fn new(builder: ::capnp::private::layout::StructBuilder<'a>) -> Builder<'a, > { + Builder { builder, } + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Builder<'a,> { + ::capnp::traits::FromStructBuilder::new(builder.init_struct(_private::STRUCT_SIZE)) + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result> { + ::core::result::Result::Ok(::capnp::traits::FromStructBuilder::new(builder.get_struct(_private::STRUCT_SIZE, default)?)) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder<'b>(pointer: ::capnp::private::layout::PointerBuilder<'b>, value: Reader<'a,>, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { .. *self } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.into_reader().total_size() + } + #[inline] + pub fn set_public(&mut self, _value: ()) { + self.builder.set_data_field::(0, 0); } #[inline] - pub fn set_publicity(&mut self, value: crate::schema_capnp::Publicity) { - self.builder.set_data_field::(0, value as u16) + pub fn set_private(&mut self, _value: ()) { + self.builder.set_data_field::(0, 1); } #[inline] - pub fn get_deprecated(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { - ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(2), ::core::option::Option::None) + pub fn set_internal(&mut self, value: crate::schema_capnp::option::Reader<'_,crate::schema_capnp::src_span::Owned>) -> ::capnp::Result<()> { + self.builder.set_data_field::(0, 2); + as ::capnp::traits::SetPointerBuilder>::set_pointer_builder(self.builder.get_pointer_field(0), value, false) } #[inline] - pub fn set_deprecated(&mut self, value: ::capnp::text::Reader<'_>) { - self.builder.get_pointer_field(2).set_text(value); + pub fn init_internal(self, ) -> crate::schema_capnp::option::Builder<'a,crate::schema_capnp::src_span::Owned> { + self.builder.set_data_field::(0, 2); + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(0), 0) } #[inline] - pub fn init_deprecated(self, size: u32) -> ::capnp::text::Builder<'a> { - self.builder.get_pointer_field(2).init_text(size) + pub fn has_internal(&self) -> bool { + if self.builder.get_data_field::(0) != 2 { return false; } + !self.builder.get_pointer_field(0).is_null() } #[inline] - pub fn has_deprecated(&self) -> bool { - !self.builder.get_pointer_field(2).is_null() + pub fn which(self) -> ::core::result::Result, ::capnp::NotInSchema> { + match self.builder.get_data_field::(0) { + 0 => { + ::core::result::Result::Ok(Public( + () + )) + } + 1 => { + ::core::result::Result::Ok(Private( + () + )) + } + 2 => { + ::core::result::Result::Ok(Internal( + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + )) + } + x => ::core::result::Result::Err(::capnp::NotInSchema(x)) + } } } @@ -2823,45 +3196,19 @@ pub mod value_constructor { } } impl Pipeline { - pub fn get_type(&self) -> crate::schema_capnp::type_::Pipeline { - ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(0)) - } - pub fn get_variant(&self) -> crate::schema_capnp::value_constructor_variant::Pipeline { - ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(1)) - } } mod _private { use capnp::private::layout; - pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 3 }; - pub const TYPE_ID: u64 = 0xd4c6_d8f1_a8fb_051c; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 1 }; + pub const TYPE_ID: u64 = 0xc549_d3c8_21e9_1c66; } -} - -#[repr(u16)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum Publicity { - Public = 0, - Private = 1, - Internal = 2, -} -impl ::capnp::traits::FromU16 for Publicity { - #[inline] - fn from_u16(value: u16) -> ::core::result::Result { - match value { - 0 => ::core::result::Result::Ok(Publicity::Public), - 1 => ::core::result::Result::Ok(Publicity::Private), - 2 => ::core::result::Result::Ok(Publicity::Internal), - n => ::core::result::Result::Err(::capnp::NotInSchema(n)), - } + pub enum Which { + Public(()), + Private(()), + Internal(A0), } -} -impl ::capnp::traits::ToU16 for Publicity { - #[inline] - fn to_u16(self) -> u16 { self as u16 } -} -impl ::capnp::traits::HasTypeId for Publicity { - #[inline] - fn type_id() -> u64 { 0xc549_d3c8_21e9_1c66u64 } + pub type WhichReader<'a,> = Which<::capnp::Result>>; + pub type WhichBuilder<'a,> = Which<::capnp::Result>>; } pub mod implementations { @@ -3200,6 +3547,9 @@ pub mod value_constructor_variant { self.builder.get_pointer_field(3).clear(); self.builder.get_pointer_field(4).clear(); self.builder.get_pointer_field(5).clear(); + self.builder.get_pointer_field(6).clear(); + self.builder.get_pointer_field(7).clear(); + self.builder.get_pointer_field(8).clear(); ::capnp::traits::FromStructBuilder::new(self.builder) } #[inline] @@ -3248,7 +3598,7 @@ pub mod value_constructor_variant { } mod _private { use capnp::private::layout; - pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 6 }; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 9 }; pub const TYPE_ID: u64 = 0xe14c_79e9_2bd0_a81a; } pub enum Which { @@ -3496,7 +3846,7 @@ pub mod value_constructor_variant { } mod _private { use capnp::private::layout; - pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 6 }; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 9 }; pub const TYPE_ID: u64 = 0x9579_9d69_8196_fbd0; } } @@ -3599,6 +3949,30 @@ pub mod value_constructor_variant { pub fn has_implementations(&self) -> bool { !self.reader.get_pointer_field(5).is_null() } + #[inline] + pub fn get_external_erlang(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(6), ::core::option::Option::None) + } + #[inline] + pub fn has_external_erlang(&self) -> bool { + !self.reader.get_pointer_field(6).is_null() + } + #[inline] + pub fn get_external_javascript(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(7), ::core::option::Option::None) + } + #[inline] + pub fn has_external_javascript(&self) -> bool { + !self.reader.get_pointer_field(7).is_null() + } + #[inline] + pub fn get_external_nix(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(8), ::core::option::Option::None) + } + #[inline] + pub fn has_external_nix(&self) -> bool { + !self.reader.get_pointer_field(8).is_null() + } } pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } @@ -3753,6 +4127,54 @@ pub mod value_constructor_variant { pub fn has_implementations(&self) -> bool { !self.builder.get_pointer_field(5).is_null() } + #[inline] + pub fn get_external_erlang(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(6), ::core::option::Option::None) + } + #[inline] + pub fn set_external_erlang(&mut self, value: crate::schema_capnp::option::Reader<'_,crate::schema_capnp::external::Owned>) -> ::capnp::Result<()> { + as ::capnp::traits::SetPointerBuilder>::set_pointer_builder(self.builder.get_pointer_field(6), value, false) + } + #[inline] + pub fn init_external_erlang(self, ) -> crate::schema_capnp::option::Builder<'a,crate::schema_capnp::external::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(6), 0) + } + #[inline] + pub fn has_external_erlang(&self) -> bool { + !self.builder.get_pointer_field(6).is_null() + } + #[inline] + pub fn get_external_javascript(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(7), ::core::option::Option::None) + } + #[inline] + pub fn set_external_javascript(&mut self, value: crate::schema_capnp::option::Reader<'_,crate::schema_capnp::external::Owned>) -> ::capnp::Result<()> { + as ::capnp::traits::SetPointerBuilder>::set_pointer_builder(self.builder.get_pointer_field(7), value, false) + } + #[inline] + pub fn init_external_javascript(self, ) -> crate::schema_capnp::option::Builder<'a,crate::schema_capnp::external::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(7), 0) + } + #[inline] + pub fn has_external_javascript(&self) -> bool { + !self.builder.get_pointer_field(7).is_null() + } + #[inline] + pub fn get_external_nix(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(8), ::core::option::Option::None) + } + #[inline] + pub fn set_external_nix(&mut self, value: crate::schema_capnp::option::Reader<'_,crate::schema_capnp::external::Owned>) -> ::capnp::Result<()> { + as ::capnp::traits::SetPointerBuilder>::set_pointer_builder(self.builder.get_pointer_field(8), value, false) + } + #[inline] + pub fn init_external_nix(self, ) -> crate::schema_capnp::option::Builder<'a,crate::schema_capnp::external::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(8), 0) + } + #[inline] + pub fn has_external_nix(&self) -> bool { + !self.builder.get_pointer_field(8).is_null() + } } pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } @@ -3771,10 +4193,19 @@ pub mod value_constructor_variant { pub fn get_implementations(&self) -> crate::schema_capnp::implementations::Pipeline { ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(5)) } + pub fn get_external_erlang(&self) -> crate::schema_capnp::option::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(6)) + } + pub fn get_external_javascript(&self) -> crate::schema_capnp::option::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(7)) + } + pub fn get_external_nix(&self) -> crate::schema_capnp::option::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(8)) + } } mod _private { use capnp::private::layout; - pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 6 }; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 9 }; pub const TYPE_ID: u64 = 0xaea6_15c5_9871_3779; } } @@ -4049,12 +4480,173 @@ pub mod value_constructor_variant { } mod _private { use capnp::private::layout; - pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 6 }; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 9 }; pub const TYPE_ID: u64 = 0xf00b_1526_e923_3dd5; } } } +pub mod external { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl <'a> ::capnp::traits::Owned<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; } + impl <'a> ::capnp::traits::OwnedStruct<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + #[derive(Clone, Copy)] + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,> ::capnp::traits::FromStructReader<'a> for Reader<'a,> { + fn new(reader: ::capnp::private::layout::StructReader<'a>) -> Reader<'a,> { + Reader { reader, } + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result> { + ::core::result::Result::Ok(::capnp::traits::FromStructReader::new(reader.get_struct(default)?)) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Reader { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_module(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn has_module(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_function(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(1), ::core::option::Option::None) + } + #[inline] + pub fn has_function(&self) -> bool { + !self.reader.get_pointer_field(1).is_null() + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + #[inline] + fn struct_size() -> ::capnp::private::layout::StructSize { _private::STRUCT_SIZE } + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,> ::capnp::traits::FromStructBuilder<'a> for Builder<'a,> { + fn new(builder: ::capnp::private::layout::StructBuilder<'a>) -> Builder<'a, > { + Builder { builder, } + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Builder<'a,> { + ::capnp::traits::FromStructBuilder::new(builder.init_struct(_private::STRUCT_SIZE)) + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result> { + ::core::result::Result::Ok(::capnp::traits::FromStructBuilder::new(builder.get_struct(_private::STRUCT_SIZE, default)?)) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder<'b>(pointer: ::capnp::private::layout::PointerBuilder<'b>, value: Reader<'a,>, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { .. *self } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.into_reader().total_size() + } + #[inline] + pub fn get_module(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn set_module(&mut self, value: ::capnp::text::Reader<'_>) { + self.builder.get_pointer_field(0).set_text(value); + } + #[inline] + pub fn init_module(self, size: u32) -> ::capnp::text::Builder<'a> { + self.builder.get_pointer_field(0).init_text(size) + } + #[inline] + pub fn has_module(&self) -> bool { + !self.builder.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_function(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) + } + #[inline] + pub fn set_function(&mut self, value: ::capnp::text::Reader<'_>) { + self.builder.get_pointer_field(1).set_text(value); + } + #[inline] + pub fn init_function(self, size: u32) -> ::capnp::text::Builder<'a> { + self.builder.get_pointer_field(1).init_text(size) + } + #[inline] + pub fn has_function(&self) -> bool { + !self.builder.get_pointer_field(1).is_null() + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Pipeline { + Pipeline { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + use capnp::private::layout; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 0, pointers: 2 }; + pub const TYPE_ID: u64 = 0xc65f_3a72_de17_d4ec; + } +} + pub mod src_span { #[derive(Copy, Clone)] pub struct Owned(()); @@ -5178,11 +5770,11 @@ pub mod constant { !self.reader.get_pointer_field(1).is_null() } #[inline] - pub fn get_typ(self) -> ::capnp::Result> { + pub fn get_type(self) -> ::capnp::Result> { ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(2), ::core::option::Option::None) } #[inline] - pub fn has_typ(&self) -> bool { + pub fn has_type(&self) -> bool { !self.reader.get_pointer_field(2).is_null() } } @@ -5268,19 +5860,19 @@ pub mod constant { !self.builder.get_pointer_field(1).is_null() } #[inline] - pub fn get_typ(self) -> ::capnp::Result> { + pub fn get_type(self) -> ::capnp::Result> { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(2), ::core::option::Option::None) } #[inline] - pub fn set_typ(&mut self, value: crate::schema_capnp::type_::Reader<'_>) -> ::capnp::Result<()> { + pub fn set_type(&mut self, value: crate::schema_capnp::type_::Reader<'_>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(2), value, false) } #[inline] - pub fn init_typ(self, ) -> crate::schema_capnp::type_::Builder<'a> { + pub fn init_type(self, ) -> crate::schema_capnp::type_::Builder<'a> { ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(2), 0) } #[inline] - pub fn has_typ(&self) -> bool { + pub fn has_type(&self) -> bool { !self.builder.get_pointer_field(2).is_null() } } @@ -5292,7 +5884,7 @@ pub mod constant { } } impl Pipeline { - pub fn get_typ(&self) -> crate::schema_capnp::type_::Pipeline { + pub fn get_type(&self) -> crate::schema_capnp::type_::Pipeline { ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(2)) } } @@ -5366,11 +5958,11 @@ pub mod constant { !self.reader.get_pointer_field(1).is_null() } #[inline] - pub fn get_typ(self) -> ::capnp::Result> { + pub fn get_type(self) -> ::capnp::Result> { ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(2), ::core::option::Option::None) } #[inline] - pub fn has_typ(&self) -> bool { + pub fn has_type(&self) -> bool { !self.reader.get_pointer_field(2).is_null() } #[inline] @@ -5464,19 +6056,19 @@ pub mod constant { !self.builder.get_pointer_field(1).is_null() } #[inline] - pub fn get_typ(self) -> ::capnp::Result> { + pub fn get_type(self) -> ::capnp::Result> { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(2), ::core::option::Option::None) } #[inline] - pub fn set_typ(&mut self, value: crate::schema_capnp::type_::Reader<'_>) -> ::capnp::Result<()> { + pub fn set_type(&mut self, value: crate::schema_capnp::type_::Reader<'_>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(2), value, false) } #[inline] - pub fn init_typ(self, ) -> crate::schema_capnp::type_::Builder<'a> { + pub fn init_type(self, ) -> crate::schema_capnp::type_::Builder<'a> { ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(2), 0) } #[inline] - pub fn has_typ(&self) -> bool { + pub fn has_type(&self) -> bool { !self.builder.get_pointer_field(2).is_null() } #[inline] @@ -5504,7 +6096,7 @@ pub mod constant { } } impl Pipeline { - pub fn get_typ(&self) -> crate::schema_capnp::type_::Pipeline { + pub fn get_type(&self) -> crate::schema_capnp::type_::Pipeline { ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(2)) } pub fn get_constructor(&self) -> crate::schema_capnp::value_constructor::Pipeline { diff --git a/compiler-core/schema.capnp b/compiler-core/schema.capnp index 5bd326e79..2273b2165 100644 --- a/compiler-core/schema.capnp +++ b/compiler-core/schema.capnp @@ -26,10 +26,16 @@ struct Module { accessors @3 :List(Property(AccessorsMap)); package @4 :Text; typesConstructors @5 :List(Property(TypesVariantConstructors)); - unusedImports @6 :List(SrcSpan); - lineNumbers @7 :LineNumbers; - srcPath @8 :Text; - isInternal @9 :Bool; + lineNumbers @6 :LineNumbers; + srcPath @7 :Text; + isInternal @8 :Bool; + requiredVersion @9 :Version; +} + +struct Version { + major @0 :UInt32; + minor @1 :UInt32; + patch @2 :UInt32; } struct TypesVariantConstructors { @@ -101,10 +107,12 @@ struct ValueConstructor { deprecated @3 :Text; } -enum Publicity { - public @0; - private @1; - internal @2; +struct Publicity { + union { + public @0 :Void; + private @1 :Void; + internal @2 :Option(SrcSpan); + } } struct Implementations { @@ -135,6 +143,9 @@ struct ValueConstructorVariant { location @7 :SrcSpan; documentation @15 :Text; implementations @18 :Implementations; + externalErlang @20 :Option(External); + externalJavascript @21 :Option(External); + externalNix @22 :Option(External); } record :group { @@ -150,6 +161,11 @@ struct ValueConstructorVariant { } } +struct External { + module @0 :Text; + function @1 :Text; +} + struct SrcSpan { start @0 :UInt32; end @1 :UInt32; @@ -185,7 +201,7 @@ struct Constant { record :group { args @6 :List(Constant); tag @7 :Text; - typ @8 :Type; + type @8 :Type; } bitArray @9 :List(BitArraySegment); @@ -193,7 +209,7 @@ struct Constant { var :group { module @10 :Text; name @11 :Text; - typ @12 :Type; + type @12 :Type; constructor @13 :ValueConstructor; } diff --git a/compiler-core/src/analyse.rs b/compiler-core/src/analyse.rs index c0270ddd3..6f7c28877 100644 --- a/compiler-core/src/analyse.rs +++ b/compiler-core/src/analyse.rs @@ -10,24 +10,26 @@ use crate::{ GroupedStatements, Import, ModuleConstant, Publicity, RecordConstructor, RecordConstructorArg, SrcSpan, Statement, TypeAlias, TypeAst, TypeAstConstructor, TypeAstFn, TypeAstHole, TypeAstTuple, TypeAstVar, TypedDefinition, TypedExpr, - TypedFunction, TypedModule, UntypedArg, UntypedFunction, UntypedModule, UntypedStatement, + TypedFunction, TypedModule, UntypedArg, UntypedCustomType, UntypedFunction, UntypedImport, + UntypedModule, UntypedModuleConstant, UntypedStatement, UntypedTypeAlias, }, build::{Origin, Outcome, Target}, call_graph::{into_dependency_order, CallGraphNode}, config::PackageConfig, dep_tree, line_numbers::LineNumbers, + parse::SpannedString, type_::{ self, environment::*, - error::{convert_unify_error, Error, MissingAnnotation, Named, Problems}, + error::{convert_unify_error, Error, FeatureKind, MissingAnnotation, Named, Problems}, expression::{ExprTyper, FunctionDefinition, Implementations}, fields::{FieldMap, FieldMapBuilder}, hydrator::Hydrator, prelude::*, AccessorsMap, Deprecation, ModuleInterface, PatternConstructor, RecordAccessor, Type, TypeConstructor, TypeValueConstructor, TypeValueConstructorField, TypeVariantConstructors, - ValueConstructor, ValueConstructorVariant, + ValueConstructor, ValueConstructorVariant, Warning, }, uid::UniqueIdGenerator, warning::TypeWarningEmitter, @@ -35,6 +37,7 @@ use crate::{ }; use camino::Utf8PathBuf; use ecow::EcoString; +use hexpm::version::Version; use itertools::Itertools; use name::{check_argument_names, check_name_case}; use std::{ @@ -137,7 +140,7 @@ pub struct ModuleAnalyzerConstructor<'a, A> { pub package_config: &'a PackageConfig, } -impl<'a, A> ModuleAnalyzerConstructor<'a, A> { +impl ModuleAnalyzerConstructor<'_, A> { /// Crawl the AST, annotating each node with the inferred type or /// returning an error. /// @@ -162,6 +165,7 @@ impl<'a, A> ModuleAnalyzerConstructor<'a, A> { value_names: HashMap::with_capacity(module.definitions.len()), hydrators: HashMap::with_capacity(module.definitions.len()), module_name: module.name.clone(), + minimum_required_version: Version::new(0, 1, 0), } .infer_module(module) } @@ -182,6 +186,9 @@ struct ModuleAnalyzer<'a, A> { value_names: HashMap, hydrators: HashMap, module_name: EcoString, + + /// The minimum Gleam version required to compile the analysed module. + minimum_required_version: Version, } impl<'a, A> ModuleAnalyzer<'a, A> { @@ -194,6 +201,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let env = Environment::new( self.ids.clone(), self.package_config.name.clone(), + self.package_config.gleam_version.clone(), self.module_name.clone(), self.target, self.importable_modules, @@ -271,7 +279,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { } // Generate warnings for unused items - let unused_imports = env.convert_unused_to_warnings(&mut self.problems); + env.convert_unused_to_warnings(&mut self.problems); // Remove imported types and values to create the public interface // Private types and values are retained so they can be used in the language @@ -321,10 +329,10 @@ impl<'a, A> ModuleAnalyzer<'a, A> { origin: self.origin, package: self.package_config.name.clone(), is_internal, - unused_imports, line_numbers: self.line_numbers, src_path: self.src_path, warnings, + minimum_required_version: self.minimum_required_version, }, }; @@ -340,7 +348,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { fn infer_module_constant( &mut self, - c: ModuleConstant<(), ()>, + c: UntypedModuleConstant, environment: &mut Environment<'_>, ) -> TypedDefinition { let ModuleConstant { @@ -367,6 +375,23 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let type_ = typed_expr.type_(); let implementations = expr_typer.implementations; + let minimum_required_version = expr_typer.minimum_required_version; + if minimum_required_version > self.minimum_required_version { + self.minimum_required_version = minimum_required_version; + } + + match publicity { + Publicity::Private + | Publicity::Public + | Publicity::Internal { + attribute_location: None, + } => (), + + Publicity::Internal { + attribute_location: Some(location), + } => self.track_feature_usage(FeatureKind::InternalAnnotation, location), + } + let variant = ValueConstructor { publicity, deprecation: deprecation.clone(), @@ -463,7 +488,6 @@ impl<'a, A> ModuleAnalyzer<'a, A> { &external_javascript, &external_nix, ); - let (impl_module, impl_function) = implementation_names(external, &self.module_name, &name); // The function must have at least one implementation somewhere. let has_implementation = self.ensure_function_has_an_implementation( @@ -510,31 +534,60 @@ impl<'a, A> ModuleAnalyzer<'a, A> { Some(prereg_return_type.clone()), )?; let args_types = args.iter().map(|a| a.type_.clone()).collect(); - let typ = fn_(args_types, body.last().type_()); - Ok((typ, body, expr_typer.implementations)) + let type_ = fn_(args_types, body.last().type_()); + Ok(( + type_, + body, + expr_typer.implementations, + expr_typer.minimum_required_version, + )) }); // If we could not successfully infer the type etc information of the // function then register the error and continue anaylsis using the best // information that we have, so we can still learn about the rest of the // module. - let (type_, body, implementations) = match result { - Ok((type_, body, implementations)) => (type_, body, implementations), + let (type_, body, implementations, required_version) = match result { + Ok((type_, body, implementations, required_version)) => { + (type_, body, implementations, required_version) + } Err(error) => { self.problems.error(error); let type_ = preregistered_type.clone(); let body = Vec1::new(Statement::Expression(TypedExpr::Invalid { - typ: prereg_return_type.clone(), + type_: prereg_return_type.clone(), location: SrcSpan { start: body_location.end, end: body_location.end, }, })); let implementations = Implementations::supporting_all(); - (type_, body, implementations) + (type_, body, implementations, Version::new(1, 0, 0)) } }; + if required_version > self.minimum_required_version { + self.minimum_required_version = required_version; + } + + match publicity { + Publicity::Private + | Publicity::Public + | Publicity::Internal { + attribute_location: None, + } => (), + + Publicity::Internal { + attribute_location: Some(location), + } => self.track_feature_usage(FeatureKind::InternalAnnotation, location), + } + + if let Some((module, _, location)) = &external_javascript { + if module.contains('@') { + self.track_feature_usage(FeatureKind::AtInJavascriptModules, *location) + } + } + // Assert that the inferred type matches the type of any recursive call if let Err(error) = unify(preregistered_type.clone(), type_) { self.problems.error(convert_unify_error(error, location)); @@ -563,9 +616,18 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let variant = ValueConstructorVariant::ModuleFn { documentation: doc.as_ref().map(|(_, doc)| doc.clone()), - name: impl_function, + name: name.clone(), + external_erlang: external_erlang + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + external_javascript: external_javascript + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + external_nix: external_nix + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), field_map, - module: impl_module, + module: environment.current_module.clone(), arity: typed_args.len(), location, implementations, @@ -602,7 +664,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { fn assert_valid_javascript_external( &mut self, function_name: &EcoString, - external_javascript: Option<&(EcoString, EcoString)>, + external_javascript: Option<&(EcoString, EcoString, SrcSpan)>, location: SrcSpan, ) { use regex::Regex; @@ -612,7 +674,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let (module, function) = match external_javascript { None => return, - Some(external) => external, + Some((module, function, _location)) => (module, function), }; if !MODULE .get_or_init(|| Regex::new("^[@a-zA-Z0-9\\./:_-]+$").expect("regex")) @@ -640,7 +702,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { fn assert_valid_nix_external( &mut self, function_name: &EcoString, - external_nix: Option<&(EcoString, EcoString)>, + external_nix: Option<&(EcoString, EcoString, SrcSpan)>, location: SrcSpan, ) { use regex::Regex; @@ -650,7 +712,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let (module, function) = match external_nix { None => return, - Some(external) => external, + Some((module, function, _location)) => (module, function), }; // TODO(NIX): Consider allowing arbitrary paths, incl. <...> notation // Currently, we force paths to be relative to something, that is, @@ -704,9 +766,9 @@ impl<'a, A> ModuleAnalyzer<'a, A> { fn ensure_function_has_an_implementation( &mut self, body: &Vec1, - external_erlang: &Option<(EcoString, EcoString)>, - external_javascript: &Option<(EcoString, EcoString)>, - external_nix: &Option<(EcoString, EcoString)>, + external_erlang: &Option<(EcoString, EcoString, SrcSpan)>, + external_javascript: &Option<(EcoString, EcoString, SrcSpan)>, + external_nix: &Option<(EcoString, EcoString, SrcSpan)>, location: SrcSpan, ) -> bool { match (external_erlang, external_javascript, external_nix) { @@ -720,7 +782,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { fn analyse_import( &mut self, - i: Import<()>, + i: UntypedImport, environment: &Environment<'_>, ) -> Option { let Import { @@ -747,12 +809,11 @@ impl<'a, A> ModuleAnalyzer<'a, A> { && module_info.package != self.package_config.name && !self.direct_dependencies.contains_key(&module_info.package) { - self.warnings - .emit(type_::Warning::TransitiveDependencyImported { - location, - module: module_info.name.clone(), - package: module_info.package.clone(), - }) + self.warnings.emit(Warning::TransitiveDependencyImported { + location, + module: module_info.name.clone(), + package: module_info.package.clone(), + }) } Some(Definition::Import(Import { @@ -768,7 +829,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { fn analyse_custom_type( &mut self, - t: CustomType<()>, + t: UntypedCustomType, environment: &mut Environment<'_>, ) -> Option { match self.do_analyse_custom_type(t, environment) { @@ -783,7 +844,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { // TODO: split this into a new class. fn do_analyse_custom_type( &mut self, - t: CustomType<()>, + t: UntypedCustomType, environment: &mut Environment<'_>, ) -> Result { self.register_values_from_custom_type( @@ -806,6 +867,18 @@ impl<'a, A> ModuleAnalyzer<'a, A> { .. } = t; + match publicity { + Publicity::Private + | Publicity::Public + | Publicity::Internal { + attribute_location: None, + } => (), + + Publicity::Internal { + attribute_location: Some(location), + } => self.track_feature_usage(FeatureKind::InternalAnnotation, location), + } + let constructors = constructors .into_iter() .map( @@ -878,7 +951,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { fn register_values_from_custom_type( &mut self, - t: &CustomType<()>, + t: &UntypedCustomType, environment: &mut Environment<'_>, type_parameters: &[&EcoString], ) -> Result<(), Error> { @@ -897,11 +970,11 @@ impl<'a, A> ModuleAnalyzer<'a, A> { .remove(name) .expect("Could not find hydrator for register_values custom type"); hydrator.disallow_new_type_variables(); - let typ = environment + let type_ = environment .module_types .get(name) .expect("Type for custom type not found in register_values") - .typ + .type_ .clone(); if let Some(accessors) = custom_type_accessors(constructors, &mut hydrator, environment, &mut self.problems)? @@ -915,19 +988,23 @@ impl<'a, A> ModuleAnalyzer<'a, A> { accessors, // TODO: improve the ownership here so that we can use the // `return_type_constructor` below rather than looking it up twice. - type_: typ.clone(), + type_: type_.clone(), }; environment.insert_accessors(name.clone(), map) } let mut constructors_data = vec![]; - for (index, constructor) in constructors.iter().enumerate() { - assert_unique_name( + let mut index = 0; + for constructor in constructors.iter() { + if let Err(error) = assert_unique_name( &mut self.value_names, &constructor.name, constructor.location, - )?; + ) { + self.problems.error(error); + continue; + } let mut field_map = FieldMap::new(constructor.arguments.len() as u32); let mut args_types = Vec::with_capacity(constructor.arguments.len()); @@ -962,9 +1039,9 @@ impl<'a, A> ModuleAnalyzer<'a, A> { } let field_map = field_map.into_option(); // Insert constructor function into module scope - let typ = match constructor.arguments.len() { - 0 => typ.clone(), - _ => fn_(args_types.clone(), typ.clone()), + let type_ = match constructor.arguments.len() { + 0 => type_.clone(), + _ => fn_(args_types.clone(), type_.clone()), }; let constructor_info = ValueConstructorVariant::Record { documentation: constructor @@ -979,6 +1056,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { module: self.module_name.clone(), constructor_index: index as u16, }; + index += 1; // If the contructor belongs to an opaque type then it's going to be // considered as private. @@ -993,7 +1071,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { ValueConstructor { publicity: value_constructor_publicity, deprecation: deprecation.clone(), - type_: typ.clone(), + type_: type_.clone(), variant: constructor_info.clone(), }, ); @@ -1014,10 +1092,16 @@ impl<'a, A> ModuleAnalyzer<'a, A> { environment.insert_variable( constructor.name.clone(), constructor_info, - typ, + type_, value_constructor_publicity, deprecation.clone(), ); + + environment.value_names.named_constructor_in_scope( + environment.current_module.clone(), + constructor.name.clone(), + constructor.name.clone(), + ); } // Now record the constructors for the type. @@ -1031,7 +1115,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { fn register_types_from_custom_type( &mut self, - t: &CustomType<()>, + t: &UntypedCustomType, environment: &mut Environment<'a>, ) -> Result<(), Error> { let CustomType { @@ -1067,15 +1151,17 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let publicity = match publicity { // It's important we only restrict the publicity of public types. Publicity::Public if self.package_config.is_internal_module(&self.module_name) => { - Publicity::Internal + Publicity::Internal { + attribute_location: None, + } } // If a type is private we don't want to make it internal just because // it comes from an internal module, so in that case the publicity is // left unchanged. - Publicity::Public | Publicity::Private | Publicity::Internal => *publicity, + Publicity::Public | Publicity::Private | Publicity::Internal { .. } => *publicity, }; - let typ = Arc::new(Type::Named { + let type_ = Arc::new(Type::Named { publicity, package: environment.current_package.clone(), module: self.module_name.to_owned(), @@ -1092,14 +1178,14 @@ impl<'a, A> ModuleAnalyzer<'a, A> { deprecation: deprecation.clone(), parameters, publicity, - typ, + type_, documentation: documentation.as_ref().map(|(_, doc)| doc.clone()), }, ) .expect("name uniqueness checked above"); if *opaque && constructors.is_empty() { - self.problems.warning(type_::Warning::OpaqueExternalType { + self.problems.warning(Warning::OpaqueExternalType { location: *location, }); } @@ -1115,7 +1201,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { Ok(()) } - fn register_type_alias(&mut self, t: &TypeAlias<()>, environment: &mut Environment<'_>) { + fn register_type_alias(&mut self, t: &UntypedTypeAlias, environment: &mut Environment<'_>) { let TypeAlias { location, publicity, @@ -1144,7 +1230,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let parameters = self.make_type_vars(args, &mut hydrator, environment); let tryblock = || { hydrator.disallow_new_type_variables(); - let typ = hydrator.type_from_ast(resolved_type, environment, &mut self.problems)?; + let type_ = hydrator.type_from_ast(resolved_type, environment, &mut self.problems)?; // Insert the alias so that it can be used by other code. environment.insert_type_constructor( @@ -1153,7 +1239,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { origin: *location, module: self.module_name.clone(), parameters, - typ, + type_, deprecation: deprecation.clone(), publicity: *publicity, documentation: documentation.as_ref().map(|(_, doc)| doc.clone()), @@ -1185,7 +1271,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> { fn make_type_vars( &mut self, - args: &[(SrcSpan, EcoString)], + args: &[SpannedString], hydrator: &mut Hydrator, environment: &mut Environment<'_>, ) -> Vec> { @@ -1263,26 +1349,34 @@ impl<'a, A> ModuleAnalyzer<'a, A> { .try_collect()?; let return_type = hydrator.type_from_option_ast(return_annotation, environment, &mut self.problems)?; - let typ = fn_(arg_types, return_type); + let type_ = fn_(arg_types, return_type); let _ = self.hydrators.insert(name.clone(), hydrator); - let external = target_function_implementation( - environment.target, - external_erlang, - external_javascript, - external_nix, - ); - let (impl_module, impl_function) = implementation_names(external, &self.module_name, name); let variant = ValueConstructorVariant::ModuleFn { documentation: documentation.as_ref().map(|(_, doc)| doc.clone()), - name: impl_function, + name: name.clone(), field_map, - module: impl_module, + external_erlang: external_erlang + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + external_javascript: external_javascript + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + external_nix: external_nix + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + module: environment.current_module.clone(), arity: args.len(), location: *location, implementations: *implementations, }; - environment.insert_variable(name.clone(), variant, typ, *publicity, deprecation.clone()); + environment.insert_variable( + name.clone(), + variant, + type_, + *publicity, + deprecation.clone(), + ); if publicity.is_private() { environment.init_usage( name.clone(), @@ -1314,6 +1408,34 @@ impl<'a, A> ModuleAnalyzer<'a, A> { self.problems.error(error); } } + + fn track_feature_usage(&mut self, feature_kind: FeatureKind, location: SrcSpan) { + let minimum_required_version = feature_kind.required_version(); + + // Then if the required version is not in the specified version for the + // range we emit a warning highlighting the usage of the feature. + if let Some(gleam_version) = &self.package_config.gleam_version { + if let Some(lowest_allowed_version) = gleam_version.lowest_version() { + // There is a version in the specified range that is lower than + // the one required by this feature! This means that the + // specified range is wrong and would allow someone to run a + // compiler that is too old to know of this feature. + if minimum_required_version > lowest_allowed_version { + self.problems + .warning(Warning::FeatureRequiresHigherGleamVersion { + location, + feature_kind, + minimum_required_version: minimum_required_version.clone(), + wrongfully_allowed_version: lowest_allowed_version, + }) + } + } + } + + if minimum_required_version > self.minimum_required_version { + self.minimum_required_version = minimum_required_version; + } + } } fn optionally_push(vector: &mut Vec, item: Option) { @@ -1337,27 +1459,12 @@ fn validate_module_name(name: &EcoString) -> Result<(), Error> { Ok(()) } -/// Returns the module name and function name of the implementation of a -/// function. If the function is implemented as a Gleam function then it is the -/// same as the name of the module and function. If the function has an external -/// implementation then it is the name of the external module and function. -fn implementation_names( - external: &Option<(EcoString, EcoString)>, - module_name: &EcoString, - name: &EcoString, -) -> (EcoString, EcoString) { - match external { - None => (module_name.clone(), name.clone()), - Some((m, f)) => (m.clone(), f.clone()), - } -} - fn target_function_implementation<'a>( target: Target, - external_erlang: &'a Option<(EcoString, EcoString)>, - external_javascript: &'a Option<(EcoString, EcoString)>, - external_nix: &'a Option<(EcoString, EcoString)>, -) -> &'a Option<(EcoString, EcoString)> { + external_erlang: &'a Option<(EcoString, EcoString, SrcSpan)>, + external_javascript: &'a Option<(EcoString, EcoString, SrcSpan)>, + external_nix: &'a Option<(EcoString, EcoString, SrcSpan)>, +) -> &'a Option<(EcoString, EcoString, SrcSpan)> { match target { Target::Erlang => external_erlang, Target::JavaScript => external_javascript, @@ -1365,7 +1472,7 @@ fn target_function_implementation<'a>( } } -fn analyse_type_alias(t: TypeAlias<()>, environment: &mut Environment<'_>) -> TypedDefinition { +fn analyse_type_alias(t: UntypedTypeAlias, environment: &mut Environment<'_>) -> TypedDefinition { let TypeAlias { documentation: doc, location, @@ -1382,8 +1489,8 @@ fn analyse_type_alias(t: TypeAlias<()>, environment: &mut Environment<'_>) -> Ty // analysis aims to be fault tolerant to get the best possible feedback for // the programmer in the language server, so the analyser gets here even // though there was previously errors. - let typ = match environment.get_type_constructor(&None, &alias) { - Ok(constructor) => constructor.typ.clone(), + let type_ = match environment.get_type_constructor(&None, &alias) { + Ok(constructor) => constructor.type_.clone(), Err(_) => environment.new_generic_var(), }; Definition::TypeAlias(TypeAlias { @@ -1394,7 +1501,7 @@ fn analyse_type_alias(t: TypeAlias<()>, environment: &mut Environment<'_>) -> Ty name_location, parameters: args, type_ast: resolved_type, - type_: typ, + type_, deprecation, }) } @@ -1480,8 +1587,8 @@ fn generalise_module_constant( deprecation, implementations, } = constant; - let typ = type_.clone(); - let type_ = type_::generalise(typ); + let type_ = type_.clone(); + let type_ = type_::generalise(type_); let variant = ValueConstructorVariant::ModuleConstant { documentation: doc.as_ref().map(|(_, doc)| doc.clone()), location, @@ -1550,24 +1657,25 @@ fn generalise_function( .get_variable(&name) .expect("Could not find preregistered type for function"); let field_map = function.field_map().cloned(); - let typ = function.type_.clone(); + let type_ = function.type_.clone(); - let type_ = type_::generalise(typ); + let type_ = type_::generalise(type_); // Insert the function into the module's interface - let external = target_function_implementation( - environment.target, - &external_erlang, - &external_javascript, - &external_nix, - ); - let (impl_module, impl_function) = implementation_names(external, module_name, &name); - let variant = ValueConstructorVariant::ModuleFn { documentation: doc.as_ref().map(|(_, doc)| doc.clone()), - name: impl_function, + name: name.clone(), field_map, - module: impl_module, + external_erlang: external_erlang + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + external_javascript: external_javascript + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + external_nix: external_nix + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + module: module_name.clone(), arity: args.len(), location, implementations, @@ -1622,7 +1730,7 @@ fn assert_unique_name( } } -fn custom_type_accessors( +fn custom_type_accessors( constructors: &[RecordConstructor], hydrator: &mut Hydrator, environment: &mut Environment<'_>, @@ -1633,13 +1741,13 @@ fn custom_type_accessors( let mut fields = HashMap::with_capacity(args.len()); hydrator.disallow_new_type_variables(); for (index, label, ast) in args { - let typ = hydrator.type_from_ast(ast, environment, problems)?; + let type_ = hydrator.type_from_ast(ast, environment, problems)?; let _ = fields.insert( label.clone(), RecordAccessor { index: index as u64, label: label.clone(), - type_: typ, + type_, }, ); } @@ -1648,7 +1756,7 @@ fn custom_type_accessors( /// Returns the fields that have the same label and type across all variants of /// the given type. -fn get_compatible_record_fields( +fn get_compatible_record_fields( constructors: &[RecordConstructor], ) -> Vec<(usize, &EcoString, &TypeAst)> { let mut compatible = vec![]; @@ -1675,6 +1783,7 @@ fn get_compatible_record_fields( }; // The labels must be the same + #[allow(clippy::nonminimal_bool)] // TODO: Bump to Rust 1.83 if !argument .label .as_ref() @@ -1699,10 +1808,10 @@ fn get_compatible_record_fields( } /// Given a type, return a list of all the types it depends on -fn get_type_dependencies(typ: &TypeAst) -> Vec { +fn get_type_dependencies(type_: &TypeAst) -> Vec { let mut deps = Vec::with_capacity(1); - match typ { + match type_ { TypeAst::Var(TypeAstVar { .. }) => (), TypeAst::Hole(TypeAstHole { .. }) => (), TypeAst::Constructor(TypeAstConstructor { @@ -1712,7 +1821,7 @@ fn get_type_dependencies(typ: &TypeAst) -> Vec { .. }) => { deps.push(match module { - Some(module) => format!("{}.{}", name, module).into(), + Some((module, _)) => format!("{}.{}", name, module).into(), None => name.clone(), }); @@ -1738,7 +1847,7 @@ fn get_type_dependencies(typ: &TypeAst) -> Vec { deps } -fn sorted_type_aliases(aliases: &Vec>) -> Result>, Error> { +fn sorted_type_aliases(aliases: &Vec) -> Result, Error> { let mut deps: Vec<(EcoString, Vec)> = Vec::with_capacity(aliases.len()); for alias in aliases { diff --git a/compiler-core/src/analyse/imports.rs b/compiler-core/src/analyse/imports.rs index 07e5fe178..930945093 100644 --- a/compiler-core/src/analyse/imports.rs +++ b/compiler-core/src/analyse/imports.rs @@ -1,7 +1,7 @@ use ecow::EcoString; use crate::{ - ast::{Import, SrcSpan, UnqualifiedImport}, + ast::{SrcSpan, UnqualifiedImport, UntypedImport}, build::Origin, type_::{ EntityKind, Environment, Error, ModuleInterface, Problems, UnusedModuleAlias, @@ -9,6 +9,8 @@ use crate::{ }, }; +use super::Imported; + #[derive(Debug)] pub struct Importer<'context, 'problems> { origin: Origin, @@ -32,7 +34,7 @@ impl<'context, 'problems> Importer<'context, 'problems> { pub fn run<'code>( origin: Origin, env: Environment<'context>, - imports: &'code [Import<()>], + imports: &'code [UntypedImport], problems: &'problems mut Problems, ) -> Environment<'context> { let mut importer = Self::new(origin, env, problems); @@ -42,7 +44,7 @@ impl<'context, 'problems> Importer<'context, 'problems> { importer.environment } - fn register_import(&mut self, import: &Import<()>) { + fn register_import(&mut self, import: &UntypedImport) { let location = import.location; let name = import.module.clone(); @@ -51,7 +53,7 @@ impl<'context, 'problems> Importer<'context, 'problems> { self.problems.error(Error::UnknownModule { location, name: name.clone(), - imported_modules: self.environment.imported_modules.keys().cloned().collect(), + suggestions: self.environment.suggest_modules(&name, Imported::Module), }); return; }; @@ -117,6 +119,17 @@ impl<'context, 'problems> Importer<'context, 'problems> { // Register the unqualified import if it is a value let variant = match module.get_public_value(import_name) { Some(value) => { + let implementations = value.variant.implementations(); + // Check the target support of the imported value + if self.environment.target_support.is_enforced() + && !implementations.supports(self.environment.target) + { + self.problems.error(Error::UnsupportedExpressionTarget { + target: self.environment.target, + location, + }) + } + self.environment.insert_variable( used_name.clone(), value.variant.clone(), @@ -139,12 +152,19 @@ impl<'context, 'problems> Importer<'context, 'problems> { }; match variant { - &ValueConstructorVariant::Record { .. } => self.environment.init_usage( - used_name.clone(), - EntityKind::ImportedConstructor, - location, - self.problems, - ), + ValueConstructorVariant::Record { name, module, .. } => { + self.environment.init_usage( + used_name.clone(), + EntityKind::ImportedConstructor, + location, + self.problems, + ); + self.environment.value_names.named_constructor_in_scope( + module.clone(), + name.clone(), + used_name.clone(), + ); + } _ => self.environment.init_usage( used_name.clone(), EntityKind::ImportedValue, @@ -189,7 +209,7 @@ impl<'context, 'problems> Importer<'context, 'problems> { fn register_module( &mut self, - import: &Import<()>, + import: &UntypedImport, import_info: &'context ModuleInterface, ) -> Result<(), Error> { if let Some(used_name) = import.used_name() { @@ -225,7 +245,11 @@ impl<'context, 'problems> Importer<'context, 'problems> { let _ = self .environment .imported_modules - .insert(used_name, (import.location, import_info)); + .insert(used_name.clone(), (import.location, import_info)); + + self.environment + .value_names + .imported_module(import.module.clone(), used_name) }; Ok(()) diff --git a/compiler-core/src/ast.rs b/compiler-core/src/ast.rs index 57bdaab8a..601fcc3d8 100644 --- a/compiler-core/src/ast.rs +++ b/compiler-core/src/ast.rs @@ -13,6 +13,7 @@ pub use self::constant::{Constant, TypedConstant, UntypedConstant}; use crate::analyse::Inferred; use crate::build::{Located, Target}; +use crate::parse::SpannedString; use crate::type_::expression::Implementations; use crate::type_::{ self, Deprecation, ModuleValueConstructor, PatternConstructor, Type, ValueConstructor, @@ -236,7 +237,7 @@ pub type TypedRecordConstructorArg = RecordConstructorArg>; #[derive(Debug, Clone, PartialEq, Eq)] pub struct RecordConstructorArg { - pub label: Option<(SrcSpan, EcoString)>, + pub label: Option, pub ast: TypeAst, pub location: SrcSpan, pub type_: T, @@ -252,7 +253,7 @@ impl RecordConstructorArg { #[derive(Debug, Clone, PartialEq, Eq)] pub struct TypeAstConstructor { pub location: SrcSpan, - pub module: Option, + pub module: Option<(EcoString, SrcSpan)>, pub name: EcoString, pub arguments: Vec, } @@ -316,7 +317,9 @@ impl TypeAst { arguments: o_arguments, location: _, }) => { - module == o_module + let module_name = + |m: &Option<(EcoString, _)>| m.as_ref().map(|(m, _)| m.clone()); + module_name(module) == module_name(o_module) && name == o_name && arguments.len() == o_arguments.len() && arguments @@ -460,7 +463,7 @@ impl TypeAst { func.return_.print(buffer); } TypeAst::Constructor(constructor) => { - if let Some(module) = &constructor.module { + if let Some((module, _)) = &constructor.module { buffer.push_str(module); buffer.push('.'); } @@ -509,7 +512,7 @@ fn type_ast_print_constructor() { let mut buffer = EcoString::new(); let ast = TypeAst::Constructor(TypeAstConstructor { name: "SomeType".into(), - module: Some("some_module".into()), + module: Some(("some_module".into(), SrcSpan { start: 1, end: 1 })), location: SrcSpan { start: 1, end: 1 }, arguments: vec![ TypeAst::Var(TypeAstVar { @@ -534,7 +537,7 @@ fn type_ast_print_tuple() { elems: vec![ TypeAst::Constructor(TypeAstConstructor { name: "SomeType".into(), - module: Some("some_module".into()), + module: Some(("some_module".into(), SrcSpan { start: 1, end: 1 })), location: SrcSpan { start: 1, end: 1 }, arguments: vec![ TypeAst::Var(TypeAstVar { @@ -577,20 +580,20 @@ fn type_ast_print_tuple() { pub enum Publicity { Public, Private, - Internal, + Internal { attribute_location: Option }, } impl Publicity { pub fn is_private(&self) -> bool { match self { Self::Private => true, - Self::Public | Self::Internal => false, + Self::Public | Self::Internal { .. } => false, } } pub fn is_internal(&self) -> bool { match self { - Self::Internal => true, + Self::Internal { .. } => true, Self::Public | Self::Private => false, } } @@ -598,13 +601,13 @@ impl Publicity { pub fn is_public(&self) -> bool { match self { Self::Public => true, - Self::Internal | Self::Private => false, + Self::Internal { .. } | Self::Private => false, } } pub fn is_importable(&self) -> bool { match self { - Self::Internal | Self::Public => true, + Self::Internal { .. } | Self::Public => true, Self::Private => false, } } @@ -629,7 +632,7 @@ impl Publicity { pub struct Function { pub location: SrcSpan, pub end_position: u32, - pub name: Option<(SrcSpan, EcoString)>, + pub name: Option, pub arguments: Vec>, pub body: Vec1>, pub publicity: Publicity, @@ -637,9 +640,9 @@ pub struct Function { pub return_annotation: Option, pub return_type: T, pub documentation: Option<(u32, EcoString)>, - pub external_erlang: Option<(EcoString, EcoString)>, - pub external_javascript: Option<(EcoString, EcoString)>, - pub external_nix: Option<(EcoString, EcoString)>, + pub external_erlang: Option<(EcoString, EcoString, SrcSpan)>, + pub external_javascript: Option<(EcoString, EcoString, SrcSpan)>, + pub external_nix: Option<(EcoString, EcoString, SrcSpan)>, pub implementations: Implementations, } @@ -647,7 +650,7 @@ pub type TypedFunction = Function, TypedExpr>; pub type UntypedFunction = Function<(), UntypedExpr>; impl Function { - fn full_location(&self) -> SrcSpan { + pub fn full_location(&self) -> SrcSpan { SrcSpan::new(self.location.start, self.end_position) } } @@ -744,7 +747,7 @@ pub struct CustomType { pub deprecation: Deprecation, pub opaque: bool, /// The names of the type parameters. - pub parameters: Vec<(SrcSpan, EcoString)>, + pub parameters: Vec, /// Once type checked this field will contain the type information for the /// type parameters. pub typed_parameters: Vec, @@ -774,7 +777,7 @@ pub struct TypeAlias { pub location: SrcSpan, pub alias: EcoString, pub name_location: SrcSpan, - pub parameters: Vec<(SrcSpan, EcoString)>, + pub parameters: Vec, pub type_ast: TypeAst, pub type_: T, pub publicity: Publicity, @@ -1732,7 +1735,7 @@ pub enum Pattern { location: SrcSpan, name: EcoString, arguments: Vec>, - module: Option, + module: Option<(EcoString, SrcSpan)>, constructor: Inferred, spread: Option, type_: Type, @@ -1780,7 +1783,7 @@ pub enum AssignName { } impl AssignName { - pub fn name(&self) -> &str { + pub fn name(&self) -> &EcoString { match self { AssignName::Variable(name) | AssignName::Discard(name) => name, } @@ -2129,9 +2132,9 @@ pub enum TodoKind { pub struct GroupedStatements { pub functions: Vec, pub constants: Vec, - pub custom_types: Vec>, - pub imports: Vec>, - pub type_aliases: Vec>, + pub custom_types: Vec, + pub imports: Vec, + pub type_aliases: Vec, } impl GroupedStatements { diff --git a/compiler-core/src/ast/constant.rs b/compiler-core/src/ast/constant.rs index ad26317b4..641daaaf9 100644 --- a/compiler-core/src/ast/constant.rs +++ b/compiler-core/src/ast/constant.rs @@ -29,16 +29,16 @@ pub enum Constant { List { location: SrcSpan, elements: Vec, - typ: T, + type_: T, }, Record { location: SrcSpan, - module: Option, + module: Option<(EcoString, SrcSpan)>, name: EcoString, args: Vec>, tag: RecordTag, - typ: T, + type_: T, field_map: Option, }, @@ -49,10 +49,10 @@ pub enum Constant { Var { location: SrcSpan, - module: Option, + module: Option<(EcoString, SrcSpan)>, name: EcoString, constructor: Option>, - typ: T, + type_: T, }, StringConcatenation { @@ -65,7 +65,7 @@ pub enum Constant { /// even when there are type errors. Should never end up in generated code. Invalid { location: SrcSpan, - typ: T, + type_: T, }, } @@ -79,10 +79,10 @@ impl TypedConstant { Constant::Tuple { elements, .. } => { type_::tuple(elements.iter().map(|e| e.type_()).collect()) } - Constant::List { typ, .. } - | Constant::Record { typ, .. } - | Constant::Var { typ, .. } - | Constant::Invalid { typ, .. } => typ.clone(), + Constant::List { type_, .. } + | Constant::Record { type_, .. } + | Constant::Var { type_, .. } + | Constant::Invalid { type_, .. } => type_.clone(), } } } diff --git a/compiler-core/src/ast/tests.rs b/compiler-core/src/ast/tests.rs index 425464587..0c4c19069 100644 --- a/compiler-core/src/ast/tests.rs +++ b/compiler-core/src/ast/tests.rs @@ -77,6 +77,7 @@ fn compile_expression(src: &str) -> TypedStatement { let mut environment = Environment::new( ids, "mypackage".into(), + None, "mymod".into(), Target::Erlang, &modules, @@ -220,7 +221,7 @@ wibble}"#, let int1 = TypedExpr::Int { location: SrcSpan { start: 14, end: 15 }, value: "1".into(), - typ: type_::int(), + type_: type_::int(), }; let var = TypedExpr::Var { @@ -262,17 +263,17 @@ fn find_node_list() { let int1 = TypedExpr::Int { location: SrcSpan { start: 1, end: 2 }, - typ: type_::int(), + type_: type_::int(), value: "1".into(), }; let int2 = TypedExpr::Int { location: SrcSpan { start: 4, end: 5 }, - typ: type_::int(), + type_: type_::int(), value: "2".into(), }; let int3 = TypedExpr::Int { location: SrcSpan { start: 7, end: 8 }, - typ: type_::int(), + type_: type_::int(), value: "3".into(), }; @@ -295,17 +296,17 @@ fn find_node_tuple() { let int1 = TypedExpr::Int { location: SrcSpan { start: 2, end: 3 }, - typ: type_::int(), + type_: type_::int(), value: "1".into(), }; let int2 = TypedExpr::Int { location: SrcSpan { start: 5, end: 6 }, - typ: type_::int(), + type_: type_::int(), value: "2".into(), }; let int3 = TypedExpr::Int { location: SrcSpan { start: 8, end: 9 }, - typ: type_::int(), + type_: type_::int(), value: "3".into(), }; @@ -342,7 +343,7 @@ fn find_node_tuple_index() { let int = TypedExpr::Int { location: SrcSpan { start: 2, end: 3 }, value: "1".into(), - typ: type_::int(), + type_: type_::int(), }; assert_eq!(expr.find_node(2), Some(Located::Expression(&int))); @@ -354,13 +355,16 @@ fn find_node_tuple_index() { fn find_node_module_select() { let expr = TypedExpr::ModuleSelect { location: SrcSpan { start: 1, end: 3 }, - typ: type_::int(), + type_: type_::int(), label: "label".into(), module_name: "name".into(), module_alias: "alias".into(), constructor: ModuleValueConstructor::Fn { module: "module".into(), name: "function".into(), + external_erlang: None, + external_javascript: None, + external_nix: None, location: SrcSpan { start: 1, end: 55 }, documentation: None, field_map: None, @@ -381,7 +385,7 @@ fn find_node_fn() { let int = TypedExpr::Int { location: SrcSpan { start: 7, end: 8 }, value: "1".into(), - typ: type_::int(), + type_: type_::int(), }; assert_eq!(expr.find_node(0), Some(Located::Expression(expr))); @@ -400,19 +404,19 @@ fn find_node_call() { let retrn = TypedExpr::Int { location: SrcSpan { start: 11, end: 12 }, value: "1".into(), - typ: type_::int(), + type_: type_::int(), }; let arg1 = TypedExpr::Int { location: SrcSpan { start: 15, end: 16 }, value: "1".into(), - typ: type_::int(), + type_: type_::int(), }; let arg2 = TypedExpr::Int { location: SrcSpan { start: 18, end: 19 }, value: "2".into(), - typ: type_::int(), + type_: type_::int(), }; assert_eq!(expr.find_node(11), Some(Located::Expression(&retrn))); @@ -432,13 +436,13 @@ fn find_node_record_access() { let string = TypedExpr::String { location: SrcSpan { start: 4, end: 10 }, value: "Nubi".into(), - typ: type_::string(), + type_: type_::string(), }; let int = TypedExpr::Int { location: SrcSpan { start: 12, end: 13 }, value: "3".into(), - typ: type_::int(), + type_: type_::int(), }; assert_eq!(access.find_node(4), Some(Located::Expression(&string))); @@ -457,7 +461,7 @@ fn find_node_record_update() { let int = TypedExpr::Int { location: SrcSpan { start: 27, end: 28 }, value: "4".into(), - typ: type_::int(), + type_: type_::int(), }; assert_eq!(update.find_node(0), Some(Located::Expression(update))); @@ -481,19 +485,19 @@ case 1, 2 { let int1 = TypedExpr::Int { location: SrcSpan { start: 6, end: 7 }, value: "1".into(), - typ: type_::int(), + type_: type_::int(), }; let int2 = TypedExpr::Int { location: SrcSpan { start: 9, end: 10 }, value: "2".into(), - typ: type_::int(), + type_: type_::int(), }; let int3 = TypedExpr::Int { location: SrcSpan { start: 23, end: 24 }, value: "3".into(), - typ: type_::int(), + type_: type_::int(), }; assert_eq!(case.find_node(1), Some(Located::Expression(case))); diff --git a/compiler-core/src/ast/typed.rs b/compiler-core/src/ast/typed.rs index 05af13bfe..c3daced0c 100644 --- a/compiler-core/src/ast/typed.rs +++ b/compiler-core/src/ast/typed.rs @@ -7,19 +7,19 @@ use crate::type_::{bool, HasType, Type, ValueConstructorVariant}; pub enum TypedExpr { Int { location: SrcSpan, - typ: Arc, + type_: Arc, value: EcoString, }, Float { location: SrcSpan, - typ: Arc, + type_: Arc, value: EcoString, }, String { location: SrcSpan, - typ: Arc, + type_: Arc, value: EcoString, }, @@ -47,30 +47,30 @@ pub enum TypedExpr { Fn { location: SrcSpan, - typ: Arc, + type_: Arc, is_capture: bool, - args: Vec>>, + args: Vec, body: Vec1, return_annotation: Option, }, List { location: SrcSpan, - typ: Arc, + type_: Arc, elements: Vec, tail: Option>, }, Call { location: SrcSpan, - typ: Arc, + type_: Arc, fun: Box, args: Vec>, }, BinOp { location: SrcSpan, - typ: Arc, + type_: Arc, name: BinOp, left: Box, right: Box, @@ -78,14 +78,14 @@ pub enum TypedExpr { Case { location: SrcSpan, - typ: Arc, + type_: Arc, subjects: Vec, clauses: Vec, EcoString>>, }, RecordAccess { location: SrcSpan, - typ: Arc, + type_: Arc, label: EcoString, index: u64, record: Box, @@ -93,7 +93,7 @@ pub enum TypedExpr { ModuleSelect { location: SrcSpan, - typ: Arc, + type_: Arc, label: EcoString, module_name: EcoString, module_alias: EcoString, @@ -102,13 +102,13 @@ pub enum TypedExpr { Tuple { location: SrcSpan, - typ: Arc, + type_: Arc, elems: Vec, }, TupleIndex { location: SrcSpan, - typ: Arc, + type_: Arc, index: u64, tuple: Box, }, @@ -128,13 +128,13 @@ pub enum TypedExpr { BitArray { location: SrcSpan, - typ: Arc, + type_: Arc, segments: Vec, }, RecordUpdate { location: SrcSpan, - typ: Arc, + type_: Arc, spread: Box, args: Vec, }, @@ -153,7 +153,7 @@ pub enum TypedExpr { /// even when there are type errors. Should never end up in generated code. Invalid { location: SrcSpan, - typ: Arc, + type_: Arc, }, } @@ -410,23 +410,23 @@ impl TypedExpr { Self::NegateBool { .. } => bool(), Self::NegateInt { value, .. } => value.type_(), Self::Var { constructor, .. } => constructor.type_.clone(), - Self::Fn { typ, .. } - | Self::Int { typ, .. } - | Self::Todo { type_: typ, .. } - | Self::Case { typ, .. } - | Self::List { typ, .. } - | Self::Call { typ, .. } - | Self::Float { typ, .. } - | Self::Panic { type_: typ, .. } - | Self::BinOp { typ, .. } - | Self::Tuple { typ, .. } - | Self::String { typ, .. } - | Self::BitArray { typ, .. } - | Self::TupleIndex { typ, .. } - | Self::ModuleSelect { typ, .. } - | Self::RecordAccess { typ, .. } - | Self::RecordUpdate { typ, .. } - | Self::Invalid { typ, .. } => typ.clone(), + Self::Fn { type_, .. } + | Self::Int { type_, .. } + | Self::Todo { type_, .. } + | Self::Case { type_, .. } + | Self::List { type_, .. } + | Self::Call { type_, .. } + | Self::Float { type_, .. } + | Self::Panic { type_, .. } + | Self::BinOp { type_, .. } + | Self::Tuple { type_, .. } + | Self::String { type_, .. } + | Self::BitArray { type_, .. } + | Self::TupleIndex { type_, .. } + | Self::ModuleSelect { type_, .. } + | Self::RecordAccess { type_, .. } + | Self::RecordUpdate { type_, .. } + | Self::Invalid { type_, .. } => type_.clone(), Self::Pipeline { finally, .. } => finally.type_(), Self::Block { statements, .. } => statements.last().type_(), } @@ -518,13 +518,23 @@ impl TypedExpr { | TypedExpr::RecordAccess { .. } | TypedExpr::TupleIndex { .. } | TypedExpr::RecordUpdate { .. } - | TypedExpr::ModuleSelect { .. } | TypedExpr::Fn { .. } => true, TypedExpr::NegateBool { value, .. } | TypedExpr::NegateInt { value, .. } => { value.is_pure_value_constructor() } + // A module select is a pure value constructor only if it is a + // record, in all other cases it could be a side-effecting function. + // For example `option.Some(1)` is pure but `io.println("a")` is + // not. + TypedExpr::ModuleSelect { constructor, .. } => match constructor { + ModuleValueConstructor::Record { .. } => true, + ModuleValueConstructor::Fn { .. } | ModuleValueConstructor::Constant { .. } => { + false + } + }, + // A pipeline is a pure value constructor if its last step is a record builder. // For example `wibble() |> wobble() |> Ok` TypedExpr::Pipeline { finally, .. } => finally.is_record_builder(), @@ -550,6 +560,10 @@ impl TypedExpr { match self { TypedExpr::Call { fun, .. } => fun.is_record_builder(), TypedExpr::Var { constructor, .. } => constructor.variant.is_record(), + TypedExpr::ModuleSelect { + constructor: ModuleValueConstructor::Record { .. }, + .. + } => true, _ => false, } } diff --git a/compiler-core/src/ast/untyped.rs b/compiler-core/src/ast/untyped.rs index 105161b10..f5407ffee 100644 --- a/compiler-core/src/ast/untyped.rs +++ b/compiler-core/src/ast/untyped.rs @@ -37,7 +37,7 @@ pub enum UntypedExpr { /// The byte location of the end of the function head before the opening bracket end_of_head_byte_index: u32, is_capture: bool, - arguments: Vec>, + arguments: Vec, body: Vec1, return_annotation: Option, }, diff --git a/compiler-core/src/ast/visit.rs b/compiler-core/src/ast/visit.rs index a76687c24..5a22ca361 100644 --- a/compiler-core/src/ast/visit.rs +++ b/compiler-core/src/ast/visit.rs @@ -49,10 +49,10 @@ use ecow::EcoString; use crate::type_::Type; use super::{ - AssignName, BinOp, BitArrayOption, BitArraySegment, CallArg, Definition, Pattern, SrcSpan, - Statement, TodoKind, TypeAst, TypedArg, TypedAssignment, TypedClause, TypedDefinition, - TypedExpr, TypedExprBitArraySegment, TypedFunction, TypedModule, TypedPattern, - TypedRecordUpdateArg, TypedStatement, Use, + AssignName, BinOp, BitArrayOption, CallArg, Definition, Pattern, SrcSpan, Statement, TodoKind, + TypeAst, TypedArg, TypedAssignment, TypedClause, TypedDefinition, TypedExpr, + TypedExprBitArraySegment, TypedFunction, TypedModule, TypedPattern, + TypedPatternBitArraySegment, TypedRecordUpdateArg, TypedStatement, Use, }; pub trait Visit<'ast> { @@ -75,28 +75,28 @@ pub trait Visit<'ast> { fn visit_typed_expr_int( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, value: &'ast EcoString, ) { - visit_typed_expr_int(self, location, typ, value); + visit_typed_expr_int(self, location, type_, value); } fn visit_typed_expr_float( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, value: &'ast EcoString, ) { - visit_typed_expr_float(self, location, typ, value); + visit_typed_expr_float(self, location, type_, value); } fn visit_typed_expr_string( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, value: &'ast EcoString, ) { - visit_typed_expr_string(self, location, typ, value); + visit_typed_expr_string(self, location, type_, value); } fn visit_typed_expr_block( @@ -128,7 +128,7 @@ pub trait Visit<'ast> { fn visit_typed_expr_fn( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, is_capture: &'ast bool, args: &'ast [TypedArg], body: &'ast [TypedStatement], @@ -137,7 +137,7 @@ pub trait Visit<'ast> { visit_typed_expr_fn( self, location, - typ, + type_, is_capture, args, body, @@ -148,59 +148,59 @@ pub trait Visit<'ast> { fn visit_typed_expr_list( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, elements: &'ast [TypedExpr], tail: &'ast Option>, ) { - visit_typed_expr_list(self, location, typ, elements, tail); + visit_typed_expr_list(self, location, type_, elements, tail); } fn visit_typed_expr_call( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, fun: &'ast TypedExpr, args: &'ast [TypedCallArg], ) { - visit_typed_expr_call(self, location, typ, fun, args); + visit_typed_expr_call(self, location, type_, fun, args); } fn visit_typed_expr_bin_op( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, name: &'ast BinOp, left: &'ast TypedExpr, right: &'ast TypedExpr, ) { - visit_typed_expr_bin_op(self, location, typ, name, left, right); + visit_typed_expr_bin_op(self, location, type_, name, left, right); } fn visit_typed_expr_case( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, subjects: &'ast [TypedExpr], clauses: &'ast [TypedClause], ) { - visit_typed_expr_case(self, location, typ, subjects, clauses); + visit_typed_expr_case(self, location, type_, subjects, clauses); } fn visit_typed_expr_record_access( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, label: &'ast EcoString, index: &'ast u64, record: &'ast TypedExpr, ) { - visit_typed_expr_record_access(self, location, typ, label, index, record); + visit_typed_expr_record_access(self, location, type_, label, index, record); } fn visit_typed_expr_module_select( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, label: &'ast EcoString, module_name: &'ast EcoString, module_alias: &'ast EcoString, @@ -209,7 +209,7 @@ pub trait Visit<'ast> { visit_typed_expr_module_select( self, location, - typ, + type_, label, module_name, module_alias, @@ -220,20 +220,20 @@ pub trait Visit<'ast> { fn visit_typed_expr_tuple( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, elems: &'ast [TypedExpr], ) { - visit_typed_expr_tuple(self, location, typ, elems); + visit_typed_expr_tuple(self, location, type_, elems); } fn visit_typed_expr_tuple_index( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, index: &'ast u64, tuple: &'ast TypedExpr, ) { - visit_typed_expr_tuple_index(self, location, typ, index, tuple); + visit_typed_expr_tuple_index(self, location, type_, index, tuple); } fn visit_typed_expr_todo( @@ -258,20 +258,20 @@ pub trait Visit<'ast> { fn visit_typed_expr_bit_array( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, segments: &'ast [TypedExprBitArraySegment], ) { - visit_typed_expr_bit_array(self, location, typ, segments); + visit_typed_expr_bit_array(self, location, type_, segments); } fn visit_typed_expr_record_update( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, spread: &'ast TypedExpr, args: &'ast [TypedRecordUpdateArg], ) { - visit_typed_expr_record_update(self, location, typ, spread, args); + visit_typed_expr_record_update(self, location, type_, spread, args); } fn visit_typed_expr_negate_bool(&mut self, location: &'ast SrcSpan, value: &'ast TypedExpr) { @@ -282,8 +282,8 @@ pub trait Visit<'ast> { visit_typed_expr_negate_int(self, location, value) } - fn visit_typed_expr_invalid(&mut self, location: &'ast SrcSpan, typ: &'ast Arc) { - visit_typed_expr_invalid(self, location, typ); + fn visit_typed_expr_invalid(&mut self, location: &'ast SrcSpan, type_: &'ast Arc) { + visit_typed_expr_invalid(self, location, type_); } fn visit_typed_statement(&mut self, stmt: &'ast TypedStatement) { @@ -387,7 +387,7 @@ pub trait Visit<'ast> { location: &'ast SrcSpan, name: &'ast EcoString, arguments: &'ast Vec>, - module: &'ast Option, + module: &'ast Option<(EcoString, SrcSpan)>, constructor: &'ast Inferred, spread: &'ast Option, type_: &'ast Arc, @@ -419,7 +419,7 @@ pub trait Visit<'ast> { fn visit_typed_pattern_bit_array( &mut self, location: &'ast SrcSpan, - segments: &'ast Vec>>, + segments: &'ast Vec, ) { visit_typed_pattern_bit_array(self, location, segments); } @@ -482,19 +482,19 @@ where match node { TypedExpr::Int { location, - typ, + type_, value, - } => v.visit_typed_expr_int(location, typ, value), + } => v.visit_typed_expr_int(location, type_, value), TypedExpr::Float { location, - typ, + type_, value, - } => v.visit_typed_expr_float(location, typ, value), + } => v.visit_typed_expr_float(location, type_, value), TypedExpr::String { location, - typ, + type_, value, - } => v.visit_typed_expr_string(location, typ, value), + } => v.visit_typed_expr_string(location, type_, value), TypedExpr::Block { location, statements, @@ -511,54 +511,54 @@ where } => v.visit_typed_expr_var(location, constructor, name), TypedExpr::Fn { location, - typ, + type_, is_capture, args, body, return_annotation, - } => v.visit_typed_expr_fn(location, typ, is_capture, args, body, return_annotation), + } => v.visit_typed_expr_fn(location, type_, is_capture, args, body, return_annotation), TypedExpr::List { location, - typ, + type_, elements, tail, - } => v.visit_typed_expr_list(location, typ, elements, tail), + } => v.visit_typed_expr_list(location, type_, elements, tail), TypedExpr::Call { location, - typ, + type_, fun, args, - } => v.visit_typed_expr_call(location, typ, fun, args), + } => v.visit_typed_expr_call(location, type_, fun, args), TypedExpr::BinOp { location, - typ, + type_, name, left, right, - } => v.visit_typed_expr_bin_op(location, typ, name, left, right), + } => v.visit_typed_expr_bin_op(location, type_, name, left, right), TypedExpr::Case { location, - typ, + type_, subjects, clauses, - } => v.visit_typed_expr_case(location, typ, subjects, clauses), + } => v.visit_typed_expr_case(location, type_, subjects, clauses), TypedExpr::RecordAccess { location, - typ, + type_, label, index, record, - } => v.visit_typed_expr_record_access(location, typ, label, index, record), + } => v.visit_typed_expr_record_access(location, type_, label, index, record), TypedExpr::ModuleSelect { location, - typ, + type_, label, module_name, module_alias, constructor, } => v.visit_typed_expr_module_select( location, - typ, + type_, label, module_name, module_alias, @@ -566,15 +566,15 @@ where ), TypedExpr::Tuple { location, - typ, + type_, elems, - } => v.visit_typed_expr_tuple(location, typ, elems), + } => v.visit_typed_expr_tuple(location, type_, elems), TypedExpr::TupleIndex { location, - typ, + type_, index, tuple, - } => v.visit_typed_expr_tuple_index(location, typ, index, tuple), + } => v.visit_typed_expr_tuple_index(location, type_, index, tuple), TypedExpr::Todo { location, message, @@ -588,20 +588,20 @@ where } => v.visit_typed_expr_panic(location, message, type_), TypedExpr::BitArray { location, - typ, + type_, segments, - } => v.visit_typed_expr_bit_array(location, typ, segments), + } => v.visit_typed_expr_bit_array(location, type_, segments), TypedExpr::RecordUpdate { location, - typ, + type_, spread, args, - } => v.visit_typed_expr_record_update(location, typ, spread, args), + } => v.visit_typed_expr_record_update(location, type_, spread, args), TypedExpr::NegateBool { location, value } => { v.visit_typed_expr_negate_bool(location, value) } TypedExpr::NegateInt { location, value } => v.visit_typed_expr_negate_int(location, value), - TypedExpr::Invalid { location, typ } => v.visit_typed_expr_invalid(location, typ), + TypedExpr::Invalid { location, type_ } => v.visit_typed_expr_invalid(location, type_), } } @@ -1132,7 +1132,7 @@ pub fn visit_typed_pattern_constructor<'a, V>( _location: &'a SrcSpan, _name: &'a EcoString, arguments: &'a Vec>, - _module: &'a Option, + _module: &'a Option<(EcoString, SrcSpan)>, _constructor: &'a Inferred, _spread: &'a Option, _type: &'a Arc, @@ -1166,7 +1166,7 @@ pub fn visit_typed_pattern_tuple<'a, V>( pub fn visit_typed_pattern_bit_array<'a, V>( v: &mut V, _location: &'a SrcSpan, - segments: &'a Vec>>, + segments: &'a Vec, ) where V: Visit<'a> + ?Sized, { diff --git a/compiler-core/src/ast_folder.rs b/compiler-core/src/ast_folder.rs index 064b92ca6..1f731403d 100644 --- a/compiler-core/src/ast_folder.rs +++ b/compiler-core/src/ast_folder.rs @@ -853,7 +853,7 @@ pub trait UntypedConstantFolder { Constant::List { location, elements, - typ: (), + type_: (), } => self.fold_constant_list(location, elements), Constant::Record { @@ -862,7 +862,7 @@ pub trait UntypedConstantFolder { name, args, tag: (), - typ: (), + type_: (), field_map: _, } => self.fold_constant_record(location, module, name, args), @@ -875,7 +875,7 @@ pub trait UntypedConstantFolder { module, name, constructor: _, - typ: (), + type_: (), } => self.fold_constant_var(location, module, name), Constant::StringConcatenation { @@ -884,7 +884,10 @@ pub trait UntypedConstantFolder { right, } => self.fold_constant_string_concatenation(location, left, right), - Constant::Invalid { location, typ: () } => self.fold_constant_invalid(location), + Constant::Invalid { + location, + type_: (), + } => self.fold_constant_invalid(location), } } @@ -916,14 +919,14 @@ pub trait UntypedConstantFolder { Constant::List { location, elements, - typ: (), + type_: (), } } fn fold_constant_record( &mut self, location: SrcSpan, - module: Option, + module: Option<(EcoString, SrcSpan)>, name: EcoString, args: Vec>, ) -> UntypedConstant { @@ -933,7 +936,7 @@ pub trait UntypedConstantFolder { name, args, tag: (), - typ: (), + type_: (), field_map: None, } } @@ -949,7 +952,7 @@ pub trait UntypedConstantFolder { fn fold_constant_var( &mut self, location: SrcSpan, - module: Option, + module: Option<(EcoString, SrcSpan)>, name: EcoString, ) -> UntypedConstant { Constant::Var { @@ -957,7 +960,7 @@ pub trait UntypedConstantFolder { module, name, constructor: None, - typ: (), + type_: (), } } @@ -975,7 +978,10 @@ pub trait UntypedConstantFolder { } fn fold_constant_invalid(&mut self, location: SrcSpan) -> UntypedConstant { - Constant::Invalid { location, typ: () } + Constant::Invalid { + location, + type_: (), + } } /// You probably don't want to override this method. @@ -991,7 +997,7 @@ pub trait UntypedConstantFolder { Constant::List { location, elements, - typ, + type_, } => { let elements = elements .into_iter() @@ -1000,7 +1006,7 @@ pub trait UntypedConstantFolder { Constant::List { location, elements, - typ, + type_, } } @@ -1010,7 +1016,7 @@ pub trait UntypedConstantFolder { name, args, tag, - typ, + type_, field_map, } => { let args = args @@ -1026,7 +1032,7 @@ pub trait UntypedConstantFolder { name, args, tag, - typ, + type_, field_map, } } @@ -1213,7 +1219,7 @@ pub trait PatternFolder { location: SrcSpan, name: EcoString, arguments: Vec>, - module: Option, + module: Option<(EcoString, SrcSpan)>, spread: Option, ) -> UntypedPattern { Pattern::Constructor { diff --git a/compiler-core/src/bit_array.rs b/compiler-core/src/bit_array.rs index 0b61faecf..db84d0a5f 100644 --- a/compiler-core/src/bit_array.rs +++ b/compiler-core/src/bit_array.rs @@ -28,7 +28,7 @@ where } struct SegmentOptionCategories<'a, T> { - typ: Option<&'a BitArrayOption>, + type_: Option<&'a BitArrayOption>, signed: Option<&'a BitArrayOption>, endian: Option<&'a BitArrayOption>, unit: Option<&'a BitArrayOption>, @@ -38,7 +38,7 @@ struct SegmentOptionCategories<'a, T> { impl SegmentOptionCategories<'_, T> { fn new() -> Self { SegmentOptionCategories { - typ: None, + type_: None, signed: None, endian: None, unit: None, @@ -52,7 +52,7 @@ impl SegmentOptionCategories<'_, T> { location: SrcSpan::default(), }; - match self.typ.unwrap_or(&default) { + match self.type_.unwrap_or(&default) { Int { .. } => crate::type_::int(), Float { .. } => crate::type_::float(), Utf8 { .. } | Utf16 { .. } | Utf32 { .. } => crate::type_::string(), @@ -96,7 +96,7 @@ where | Utf8Codepoint { .. } | Utf16Codepoint { .. } | Utf32Codepoint { .. } => { - if let Some(previous) = categories.typ { + if let Some(previous) = categories.type_ { return err( ErrorType::ConflictingTypeOptions { existing_type: previous.label(), @@ -104,7 +104,7 @@ where option.location(), ); } else { - categories.typ = Some(option); + categories.type_ = Some(option); } } @@ -159,7 +159,7 @@ where signed: Some(opt), .. } | SegmentOptionCategories { - typ: Some(opt @ Bytes { .. }), + type_: Some(opt @ Bytes { .. }), .. } => return err(ErrorType::OptionNotAllowedInValue, opt.location()), _ => (), @@ -169,7 +169,7 @@ where // All but the last segment in a pattern must have an exact size if must_have_size { if let SegmentOptionCategories { - typ: Some(opt @ (Bytes { .. } | Bits { .. })), + type_: Some(opt @ (Bytes { .. } | Bits { .. })), size: None, .. } = categories @@ -181,7 +181,7 @@ where // Endianness is only valid for int, utf16, utf32 and float match categories { SegmentOptionCategories { - typ: None | Some(Int { .. } | Utf16 { .. } | Utf32 { .. } | Float { .. }), + type_: None | Some(Int { .. } | Utf16 { .. } | Utf32 { .. } | Float { .. }), .. } => {} @@ -196,17 +196,17 @@ where // signed and unsigned can only be used with int types match categories { SegmentOptionCategories { - typ: None | Some(Int { .. }), + type_: None | Some(Int { .. }), .. } => {} SegmentOptionCategories { - typ: Some(opt), + type_: Some(opt), signed: Some(sign), .. } => { return err( - ErrorType::SignednessUsedOnNonInt { typ: opt.label() }, + ErrorType::SignednessUsedOnNonInt { type_: opt.label() }, sign.location(), ); } @@ -217,24 +217,28 @@ where // utf8, utf16, utf32 exclude unit and size match categories { SegmentOptionCategories { - typ: Some(typ), + type_: Some(type_), unit: Some(_), .. - } if is_unicode(typ) => { + } if is_unicode(type_) => { return err( - ErrorType::TypeDoesNotAllowUnit { typ: typ.label() }, - typ.location(), + ErrorType::TypeDoesNotAllowUnit { + type_: type_.label(), + }, + type_.location(), ); } SegmentOptionCategories { - typ: Some(typ), + type_: Some(type_), size: Some(_), .. - } if is_unicode(typ) => { + } if is_unicode(type_) => { return err( - ErrorType::TypeDoesNotAllowSize { typ: typ.label() }, - typ.location(), + ErrorType::TypeDoesNotAllowSize { + type_: type_.label(), + }, + type_.location(), ); } @@ -253,7 +257,7 @@ where // float only 16/32/64 if let SegmentOptionCategories { - typ: Some(Float { .. }), + type_: Some(Float { .. }), size: Some(size), .. } = categories @@ -276,7 +280,7 @@ pub trait GetLiteralValue { fn as_int_literal(&self) -> Option; } -impl GetLiteralValue for crate::ast::Pattern> { +impl GetLiteralValue for crate::ast::TypedPattern { fn as_int_literal(&self) -> Option { match self { crate::ast::Pattern::Int { value, .. } => { @@ -326,9 +330,9 @@ pub enum ErrorType { InvalidEndianness, OptionNotAllowedInValue, SegmentMustHaveSize, - SignednessUsedOnNonInt { typ: EcoString }, - TypeDoesNotAllowSize { typ: EcoString }, - TypeDoesNotAllowUnit { typ: EcoString }, + SignednessUsedOnNonInt { type_: EcoString }, + TypeDoesNotAllowSize { type_: EcoString }, + TypeDoesNotAllowUnit { type_: EcoString }, UnitMustHaveSize, VariableUtfSegmentInPattern, } diff --git a/compiler-core/src/build.rs b/compiler-core/src/build.rs index 65fbacf35..a581ce626 100644 --- a/compiler-core/src/build.rs +++ b/compiler-core/src/build.rs @@ -97,6 +97,20 @@ impl Target { } } +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +/// This is used to skip compiling the root package when running the main +/// function coming from a dependency. This way a dependency can be run even +/// there's compilation errors in the root package. +/// +pub enum Compile { + /// The default compiler behaviour, compile all packages. + /// + All, + /// Only compile the dependency packages, skipping the root package. + /// + DepsOnly, +} + #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum Codegen { All, @@ -325,7 +339,7 @@ pub enum Located<'a> { Pattern(&'a TypedPattern), PatternSpread { spread_location: SrcSpan, - arguments: &'a Vec>>>, + arguments: &'a Vec>, }, Statement(&'a TypedStatement), Expression(&'a TypedExpr), diff --git a/compiler-core/src/build/package_compiler.rs b/compiler-core/src/build/package_compiler.rs index 1093f77b3..f51883db7 100644 --- a/compiler-core/src/build/package_compiler.rs +++ b/compiler-core/src/build/package_compiler.rs @@ -43,6 +43,13 @@ pub struct PackageCompiler<'a, IO> { pub ids: UniqueIdGenerator, pub write_metadata: bool, pub perform_codegen: bool, + /// If set to false the compiler won't load and analyse any of the package's + /// modules and always succeed compilation returning no compile modules. + /// + /// Code generation is still carried out so that a root package will have an + /// entry point nonetheless. + /// + pub compile_modules: bool, pub write_entrypoint: bool, pub copy_native_files: bool, pub compile_beam_bytecode: bool, @@ -76,6 +83,7 @@ where target, write_metadata: true, perform_codegen: true, + compile_modules: true, write_entrypoint: false, copy_native_files: true, compile_beam_bytecode: true, @@ -112,6 +120,7 @@ where } else { CodegenRequired::No }; + let loader = PackageLoader::new( self.io.clone(), self.ids.clone(), @@ -127,9 +136,14 @@ where already_defined_modules, incomplete_modules, ); - let loaded = match loader.run() { - Ok(loaded) => loaded, - Err(error) => return error.into(), + + let loaded = if self.compile_modules { + match loader.run() { + Ok(loaded) => loaded, + Err(error) => return error.into(), + } + } else { + Loaded::empty() }; // Load the cached modules that have previously been compiled @@ -168,6 +182,7 @@ where self.target_support, incomplete_modules, ); + let modules = match outcome { Outcome::Ok(modules) => modules, Outcome::PartialFailure(_, _) | Outcome::TotalFailure(_) => return outcome, @@ -675,6 +690,15 @@ pub(crate) struct Loaded { pub cached: Vec, } +impl Loaded { + fn empty() -> Self { + Self { + to_compile: vec![], + cached: vec![], + } + } +} + #[derive(Debug, PartialEq, Eq)] pub(crate) struct UncompiledModule { pub path: Utf8PathBuf, diff --git a/compiler-core/src/build/package_loader/tests.rs b/compiler-core/src/build/package_loader/tests.rs index d81c52001..a29ec58ba 100644 --- a/compiler-core/src/build/package_loader/tests.rs +++ b/compiler-core/src/build/package_loader/tests.rs @@ -1,4 +1,5 @@ use ecow::{eco_format, EcoString}; +use hexpm::version::Version; use super::*; use crate::{ @@ -55,11 +56,11 @@ fn write_cache( types_value_constructors: Default::default(), values: Default::default(), accessors: Default::default(), - unused_imports: Vec::new(), line_numbers: line_numbers.clone(), is_internal: false, src_path: Utf8PathBuf::from(format!("/src/{}.gleam", name)), warnings: vec![], + minimum_required_version: Version::new(0, 1, 0), }; let path = Utf8Path::new("/artefact").join(format!("{name}.cache")); fs.write_bytes( diff --git a/compiler-core/src/build/project_compiler.rs b/compiler-core/src/build/project_compiler.rs index 3ee4a0508..846fd9e5d 100644 --- a/compiler-core/src/build/project_compiler.rs +++ b/compiler-core/src/build/project_compiler.rs @@ -19,17 +19,21 @@ use crate::{ Error, Result, Warning, }; use ecow::EcoString; +use hexpm::version::Version; use itertools::Itertools; +use pubgrub::range::Range; use std::{ + cmp, collections::{HashMap, HashSet}, fmt::Write, io::BufReader, + rc::Rc, sync::Arc, time::Instant, }; use super::{ - elixir_libraries::ElixirLibraries, package_compiler::CachedWarnings, Codegen, + elixir_libraries::ElixirLibraries, package_compiler::CachedWarnings, Codegen, Compile, ErlangAppCodegenConfiguration, Outcome, }; @@ -51,9 +55,11 @@ const ELIXIR_EXECUTABLE: &str = "elixir.bat"; pub struct Options { pub mode: Mode, pub target: Option, + pub compile: Compile, pub codegen: Codegen, pub warnings_as_errors: bool, pub root_target_support: TargetSupport, + pub no_print_progress: bool, } #[derive(Debug)] @@ -77,6 +83,15 @@ impl Built { }), } } + + pub fn minimum_required_version(&self) -> Version { + self.module_interfaces + .values() + .map(|interface| &interface.minimum_required_version) + .reduce(|one_version, other_version| cmp::max(one_version, other_version)) + .map(|minimum_required_version| minimum_required_version.clone()) + .unwrap_or(Version::new(0, 1, 0)) + } } #[derive(Debug)] @@ -91,7 +106,7 @@ pub struct ProjectCompiler { /// successful compilation. incomplete_modules: HashSet, warnings: WarningEmitter, - telemetry: Box, + telemetry: &'static dyn Telemetry, options: Options, paths: ProjectPaths, ids: UniqueIdGenerator, @@ -112,8 +127,8 @@ where config: PackageConfig, options: Options, packages: Vec, - telemetry: Box, - warning_emitter: Arc, + telemetry: &'static dyn Telemetry, + warning_emitter: Rc, paths: ProjectPaths, io: IO, ) -> Self { @@ -347,7 +362,7 @@ where let env = [ ("ERL_LIBS", "../*/ebin".into()), - ("REBAR_BARE_COMPILER_OUTPUT_DIR", "./".into()), + ("REBAR_BARE_COMPILER_OUTPUT_DIR", package_build.to_string()), ("REBAR_PROFILE", "prod".into()), ("TERM", "dumb".into()), ]; @@ -559,6 +574,7 @@ where compiler.write_entrypoint = is_root; compiler.perform_codegen = self.options.codegen.should_codegen(is_root); compiler.compile_beam_bytecode = self.options.codegen.should_codegen(is_root); + compiler.compile_modules = !(self.options.compile == Compile::DepsOnly && is_root); compiler.subprocess_stdio = self.subprocess_stdio; compiler.target_support = if is_root { // When compiling the root package it is context specific as to whether we need to @@ -587,7 +603,7 @@ where &mut self.defined_modules, &mut self.stale_modules, &mut self.incomplete_modules, - self.telemetry.as_ref(), + self.telemetry, ) } } diff --git a/compiler-core/src/build/telemetry.rs b/compiler-core/src/build/telemetry.rs index 095ac3594..6fb793956 100644 --- a/compiler-core/src/build/telemetry.rs +++ b/compiler-core/src/build/telemetry.rs @@ -7,10 +7,13 @@ use crate::Warning; pub trait Telemetry: Debug { fn waiting_for_build_directory_lock(&self); + fn running(&self, name: &str); fn resolving_package_versions(&self); fn downloading_package(&self, name: &str); fn packages_downloaded(&self, start: Instant, count: usize); + fn compiled_package(&self, duration: Duration); fn compiling_package(&self, name: &str); + fn checked_package(&self, duration: Duration); fn checking_package(&self, name: &str); } @@ -19,9 +22,12 @@ pub struct NullTelemetry; impl Telemetry for NullTelemetry { fn waiting_for_build_directory_lock(&self) {} + fn running(&self, name: &str) {} fn resolving_package_versions(&self) {} fn downloading_package(&self, _name: &str) {} + fn compiled_package(&self, _duration: Duration) {} fn compiling_package(&self, _name: &str) {} + fn checked_package(&self, _duration: Duration) {} fn checking_package(&self, _name: &str) {} fn packages_downloaded(&self, _start: Instant, _count: usize) {} } diff --git a/compiler-core/src/call_graph.rs b/compiler-core/src/call_graph.rs index 710857f6a..91944ec1a 100644 --- a/compiler-core/src/call_graph.rs +++ b/compiler-core/src/call_graph.rs @@ -4,11 +4,11 @@ #[cfg(test)] mod into_dependency_order_tests; -use crate::ast::{ModuleConstant, UntypedModuleConstant}; use crate::{ ast::{ AssignName, BitArrayOption, ClauseGuard, Constant, Pattern, SrcSpan, Statement, - UntypedExpr, UntypedFunction, UntypedPattern, UntypedStatement, + UntypedClauseGuard, UntypedExpr, UntypedFunction, UntypedModuleConstant, UntypedPattern, + UntypedStatement, }, type_::Error, Result, @@ -28,7 +28,7 @@ struct CallGraphBuilder<'a> { pub enum CallGraphNode { Function(UntypedFunction), - ModuleConstant(ModuleConstant<(), ()>), + ModuleConstant(UntypedModuleConstant), } impl<'a> CallGraphBuilder<'a> { @@ -389,7 +389,7 @@ impl<'a> CallGraphBuilder<'a> { } } - fn guard(&mut self, guard: &'a ClauseGuard<(), ()>) { + fn guard(&mut self, guard: &'a UntypedClauseGuard) { match guard { ClauseGuard::Equals { left, right, .. } | ClauseGuard::NotEquals { left, right, .. } diff --git a/compiler-core/src/call_graph/into_dependency_order_tests.rs b/compiler-core/src/call_graph/into_dependency_order_tests.rs index e23b8a4e5..1038affcd 100644 --- a/compiler-core/src/call_graph/into_dependency_order_tests.rs +++ b/compiler-core/src/call_graph/into_dependency_order_tests.rs @@ -1,6 +1,6 @@ use super::*; use crate::{ - ast::{Arg, Function, Publicity}, + ast::{Arg, Function, ModuleConstant, Publicity}, type_::{expression::Implementations, Deprecation}, }; use ecow::EcoString; diff --git a/compiler-core/src/config.rs b/compiler-core/src/config.rs index 8cc7bf5d6..52e8024f5 100644 --- a/compiler-core/src/config.rs +++ b/compiler-core/src/config.rs @@ -7,7 +7,7 @@ use crate::{Error, Result}; use camino::{Utf8Path, Utf8PathBuf}; use ecow::EcoString; use globset::{Glob, GlobSetBuilder}; -use hexpm::version::Version; +use hexpm::version::{self, Version}; use http::Uri; use serde::Deserialize; use std::collections::{HashMap, HashSet}; @@ -73,8 +73,13 @@ pub struct PackageConfig { pub name: EcoString, #[serde(default = "default_version")] pub version: Version, - #[serde(default, rename = "gleam")] - pub gleam_version: Option, + #[serde( + default, + rename = "gleam", + serialize_with = "serialise_range", + deserialize_with = "deserialise_range" + )] + pub gleam_version: Option>, #[serde(default, alias = "licenses")] pub licences: Vec, #[serde(default)] @@ -101,6 +106,35 @@ pub struct PackageConfig { pub glistix: GlistixConfig, } +pub fn serialise_range( + range: Option>, + serialiser: S, +) -> Result +where + S: serde::Serializer, +{ + match range { + Some(range) => serialiser.serialize_some(&range.to_string()), + None => serialiser.serialize_none(), + } +} + +pub fn deserialise_range<'de, D>( + deserialiser: D, +) -> Result>, D::Error> +where + D: serde::Deserializer<'de>, +{ + match Deserialize::deserialize(deserialiser)? { + Some(range_string) => Ok(Some( + version::Range::new(range_string) + .to_pubgrub() + .map_err(serde::de::Error::custom)?, + )), + None => Ok(None), + } +} + impl PackageConfig { pub fn dependencies_for(&self, mode: Mode) -> Result { match mode { @@ -185,15 +219,9 @@ impl PackageConfig { // Checks to see if the gleam version specified in the config is compatible // with the current compiler version pub fn check_gleam_compatibility(&self) -> Result<(), Error> { - if let Some(required_version) = &self.gleam_version { + if let Some(range) = &self.gleam_version { let compiler_version = Version::parse(COMPILER_VERSION).expect("Parse compiler semantic version"); - let range = hexpm::version::Range::new(required_version.to_string()) - .to_pubgrub() - .map_err(|error| Error::InvalidVersionFormat { - input: required_version.to_string(), - error: error.to_string(), - })?; // We ignore the pre-release and build metadata when checking compatibility let mut version_without_pre = compiler_version.clone(); @@ -202,7 +230,7 @@ impl PackageConfig { if !range.contains(&version_without_pre) { return Err(Error::IncompatibleCompilerVersion { package: self.name.to_string(), - required_version: required_version.to_string(), + required_version: range.to_string(), gleam_version: COMPILER_VERSION.to_string(), }); } @@ -759,7 +787,7 @@ pub enum Repository { user: String, repo: String, }, - CodeBerg { + Codeberg { user: String, repo: String, }, @@ -788,7 +816,7 @@ impl Repository { Repository::BitBucket { repo, user } => { Some(format!("https://bitbucket.com/{user}/{repo}")) } - Repository::CodeBerg { repo, user } => { + Repository::Codeberg { repo, user } => { Some(format!("https://codeberg.org/{user}/{repo}")) } Repository::SourceHut { repo, user } => { diff --git a/compiler-core/src/dependency.rs b/compiler-core/src/dependency.rs index ef3e69b29..5d9d2f96d 100644 --- a/compiler-core/src/dependency.rs +++ b/compiler-core/src/dependency.rs @@ -211,7 +211,7 @@ impl<'a> DependencyProvider<'a> { type PackageName = String; -impl<'a> pubgrub::solver::DependencyProvider for DependencyProvider<'a> { +impl pubgrub::solver::DependencyProvider for DependencyProvider<'_> { fn choose_package_version, Ver: Borrow>( &self, potential_packages: impl Iterator, diff --git a/compiler-core/src/docs.rs b/compiler-core/src/docs.rs index 607d80fdb..4bdf025ce 100644 --- a/compiler-core/src/docs.rs +++ b/compiler-core/src/docs.rs @@ -96,7 +96,7 @@ pub fn generate_html( let path = [&m.name, ".html"].concat(); Link { path, - name: m.name.to_string(), + name: m.name.split('/').join("/"), } }) .sorted() @@ -186,8 +186,8 @@ pub fn generate_html( .sorted() .collect(); - types.iter().for_each(|typ| { - let constructors = typ + types.iter().for_each(|type_| { + let constructors = type_ .constructors .iter() .map(|constructor| { @@ -206,15 +206,15 @@ pub fn generate_html( search_indexes.push(SearchIndex { doc: module.name.to_string(), - title: typ.name.to_string(), + title: type_.name.to_string(), content: format!( "{}\n{}\n{}\n{}", - typ.definition, - typ.text_documentation, + type_.definition, + type_.text_documentation, constructors, - import_synonyms(&module.name, typ.name) + import_synonyms(&module.name, type_.name) ), - url: format!("{}.html#{}", module.name, typ.name), + url: format!("{}.html#{}", module.name, type_.name), }) }); constants.iter().for_each(|constant| { @@ -670,7 +670,7 @@ fn type_<'a>(source_links: &SourceLinker, statement: &'a TypedDefinition) -> Opt Definition::TypeAlias(TypeAlias { publicity: Publicity::Public, alias: name, - type_ast: typ, + type_ast: type_, documentation: doc, parameters: args, location, @@ -680,7 +680,7 @@ fn type_<'a>(source_links: &SourceLinker, statement: &'a TypedDefinition) -> Opt name, definition: print( formatter - .type_alias(Publicity::Public, name, args, typ, deprecation, location) + .type_alias(Publicity::Public, name, args, type_, deprecation, location) .group(), ), documentation: markdown_documentation(doc), diff --git a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__discarded_arguments_are_not_shown.snap b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__discarded_arguments_are_not_shown.snap index 0a3be6185..7d4f91290 100644 --- a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__discarded_arguments_are_not_shown.snap +++ b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__discarded_arguments_are_not_shown.snap @@ -218,7 +218,7 @@ expression: "compile(config, modules)"

Modules

@@ -349,7 +349,7 @@ expression: "compile(config, modules)" }); hljs.highlightAll(); - + diff --git a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__docs_of_a_type_constructor_are_not_used_by_the_following_function.snap b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__docs_of_a_type_constructor_are_not_used_by_the_following_function.snap index 1e578491b..ffca66301 100644 --- a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__docs_of_a_type_constructor_are_not_used_by_the_following_function.snap +++ b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__docs_of_a_type_constructor_are_not_used_by_the_following_function.snap @@ -218,7 +218,7 @@ expression: "compile(config, modules)"

Modules

@@ -424,7 +424,7 @@ expression: "compile(config, modules)" }); hljs.highlightAll(); - + diff --git a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__hello_docs.snap b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__hello_docs.snap index 8c828cb33..c7623eab9 100644 --- a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__hello_docs.snap +++ b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__hello_docs.snap @@ -218,7 +218,7 @@ expression: "compile(config, modules)"

Modules

@@ -350,7 +350,7 @@ expression: "compile(config, modules)" }); hljs.highlightAll(); - + diff --git a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__internal_definitions_are_not_included.snap b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__internal_definitions_are_not_included.snap index fbeb462e1..01dfad492 100644 --- a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__internal_definitions_are_not_included.snap +++ b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__internal_definitions_are_not_included.snap @@ -218,7 +218,7 @@ expression: "compile(config, modules)"

Modules

@@ -319,7 +319,7 @@ expression: "compile(config, modules)" }); hljs.highlightAll(); - + diff --git a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__long_function_wrapping.snap b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__long_function_wrapping.snap index 959ea488a..5f2cfc351 100644 --- a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__long_function_wrapping.snap +++ b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__long_function_wrapping.snap @@ -218,7 +218,7 @@ expression: "compile(config, modules)"

Modules

@@ -423,7 +423,7 @@ function for a fallback value.

}); hljs.highlightAll(); - + diff --git a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_function_comment_is_trimmed.snap b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_function_comment_is_trimmed.snap index d5db018c9..2cbf7058d 100644 --- a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_function_comment_is_trimmed.snap +++ b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_function_comment_is_trimmed.snap @@ -218,7 +218,7 @@ expression: "compile(config, modules)"

Modules

@@ -353,7 +353,7 @@ expression: "compile(config, modules)" }); hljs.highlightAll(); - + diff --git a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_module_comment_is_trimmed.snap b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_module_comment_is_trimmed.snap index 17aaae6a5..2f905be53 100644 --- a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_module_comment_is_trimmed.snap +++ b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_module_comment_is_trimmed.snap @@ -218,7 +218,7 @@ expression: "compile(config, modules)"

Modules

@@ -323,7 +323,7 @@ expression: "compile(config, modules)" }); hljs.highlightAll(); - + diff --git a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_standalone_pages_is_not_trimmed.snap b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_standalone_pages_is_not_trimmed.snap index d159565a8..8a60b0767 100644 --- a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_standalone_pages_is_not_trimmed.snap +++ b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__markdown_code_from_standalone_pages_is_not_trimmed.snap @@ -313,7 +313,7 @@ expression: "compile_with_markdown_pages(config, vec![], pages)" }); hljs.highlightAll(); - + diff --git a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__tables.snap b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__tables.snap index 836016b91..f317785a6 100644 --- a/compiler-core/src/docs/snapshots/glistix_core__docs__tests__tables.snap +++ b/compiler-core/src/docs/snapshots/glistix_core__docs__tests__tables.snap @@ -218,7 +218,7 @@ expression: "compile(config, modules)"

Modules

@@ -353,7 +353,7 @@ expression: "compile(config, modules)" }); hljs.highlightAll(); - + diff --git a/compiler-core/src/docs/source_links.rs b/compiler-core/src/docs/source_links.rs index 37056a78d..fe289231f 100644 --- a/compiler-core/src/docs/source_links.rs +++ b/compiler-core/src/docs/source_links.rs @@ -49,23 +49,23 @@ impl SourceLinker { ), ":".into(), )), - Repository::CodeBerg { user, repo } => Some(( + Repository::Codeberg { user, repo } => Some(( format!( - "https://codeberg.org/{}/{}/src/tag/{}/{}#L", + "https://codeberg.org/{}/{}/src/tag/v{}/{}#L", user, repo, project_config.version, path_in_repo ), "-".into(), )), Repository::SourceHut { user, repo } => Some(( format!( - "https://git.sr.ht/~{}/{}/tree/{}/item/{}#L", + "https://git.sr.ht/~{}/{}/tree/v{}/item/{}#L", user, repo, project_config.version, path_in_repo ), "-".into(), )), Repository::Gitea { user, repo, host } => Some(( format!( - "{host}/{user}/{repo}/src/tag/{}/{}#L", + "{host}/{user}/{repo}/src/tag/v{}/{}#L", project_config.version, path_in_repo ), "-".into(), diff --git a/compiler-core/src/erlang.rs b/compiler-core/src/erlang.rs index f75f228d2..fe74810c3 100644 --- a/compiler-core/src/erlang.rs +++ b/compiler-core/src/erlang.rs @@ -215,11 +215,13 @@ fn module_document<'a>( join(type_defs, lines(2)).append(lines(2)) }; + let src_path = EcoString::from(module.type_info.src_path.as_str()); + let statements = join( module .definitions .iter() - .flat_map(|s| module_statement(s, &module.name, line_numbers)), + .flat_map(|s| module_statement(s, &module.name, line_numbers, &src_path)), lines(2), ); @@ -350,6 +352,7 @@ fn module_statement<'a>( statement: &'a TypedDefinition, module: &'a str, line_numbers: &'a LineNumbers, + src_path: &EcoString, ) -> Option> { match statement { Definition::TypeAlias(TypeAlias { .. }) @@ -357,7 +360,9 @@ fn module_statement<'a>( | Definition::Import(Import { .. }) | Definition::ModuleConstant(ModuleConstant { .. }) => None, - Definition::Function(function) => module_function(function, module, line_numbers), + Definition::Function(function) => { + module_function(function, module, line_numbers, src_path.clone()) + } } } @@ -365,6 +370,7 @@ fn module_function<'a>( function: &'a TypedFunction, module: &'a str, line_numbers: &'a LineNumbers, + src_path: EcoString, ) -> Option> { // Private external functions don't need to render anything, the underlying // Erlang implementation is used directly at the call site. @@ -383,6 +389,7 @@ fn module_function<'a>( .as_ref() .expect("A module's function must be named"); let function_name = escape_erlang_existing_name(function_name); + let file_attribute = file_attribute(src_path, function, line_numbers); let mut env = Env::new(module, function_name, line_numbers); let var_usages = collect_type_var_usages( @@ -395,13 +402,14 @@ fn module_function<'a>( .iter() .map(|a| type_printer.print(&a.type_)); let return_spec = type_printer.print(&function.return_type); + let spec = fun_spec(function_name, args_spec, return_spec); let arguments = fun_args(&function.arguments, &mut env); let body = function .external_erlang .as_ref() - .map(|(module, function)| { + .map(|(module, function, _location)| { docvec![ atom(module), ":", @@ -411,15 +419,25 @@ fn module_function<'a>( }) .unwrap_or_else(|| statement_sequence(&function.body, &mut env)); - let doc = spec - .append(atom_string( - escape_erlang_existing_name(function_name).to_string(), - )) - .append(arguments) - .append(" ->") - .append(line().append(body).nest(INDENT).group()) - .append("."); - Some(doc) + Some(docvec![ + file_attribute, + line(), + spec, + atom_string(escape_erlang_existing_name(function_name).to_string()), + arguments, + " ->", + line().append(body).nest(INDENT).group(), + ".", + ]) +} + +fn file_attribute<'a>( + path: EcoString, + function: &'a TypedFunction, + line_numbers: &'a LineNumbers, +) -> Document<'a> { + let line = line_numbers.line_number(function.location.start); + docvec!["-file(\"", path, "\", ", line, ")."] } fn fun_args<'a>(args: &'a [TypedArg], env: &mut Env<'a>) -> Document<'a> { @@ -647,12 +665,16 @@ fn bit_array<'a>(elems: impl IntoIterator>) -> Document<'a> fn const_segment<'a>( value: &'a TypedConstant, - options: &'a [BitArrayOption], + options: &'a [TypedConstantBitArraySegmentOption], env: &mut Env<'a>, ) -> Document<'a> { + let mut value_is_a_string_literal = false; let document = match value { // Skip the normal <> surrounds - Constant::String { value, .. } => value.to_doc().surround("\"", "\""), + Constant::String { value, .. } => { + value_is_a_string_literal = true; + value.to_doc().surround("\"", "\"") + } // As normal Constant::Int { .. } | Constant::Float { .. } | Constant::BitArray { .. } => { @@ -673,7 +695,15 @@ fn const_segment<'a>( let unit = |value: &'a u8| Some(Document::String(format!("unit:{value}"))); - bit_array_segment(document, options, size, unit, true, env) + bit_array_segment( + document, + options, + size, + unit, + value_is_a_string_literal, + false, + env, + ) } fn statement<'a>(statement: &'a TypedStatement, env: &mut Env<'a>) -> Document<'a> { @@ -738,6 +768,7 @@ fn expr_segment<'a>( size, unit, value_is_a_string_literal, + false, env, ) } @@ -748,6 +779,7 @@ fn bit_array_segment<'a, Value: 'a, SizeToDoc, UnitToDoc>( mut size_to_doc: SizeToDoc, mut unit_to_doc: UnitToDoc, value_is_a_string_literal: bool, + value_is_a_discard: bool, env: &mut Env<'a>, ) -> Document<'a> where @@ -761,7 +793,7 @@ where // Erlang only allows valid codepoint integers to be used as values for utf segments // We want to support <> for all string variables, but <> is invalid // To work around this we use the binary type specifier for these segments instead - let override_type = if !value_is_a_string_literal { + let override_type = if !value_is_a_string_literal && !value_is_a_discard { Some("binary") } else { None @@ -973,7 +1005,7 @@ fn let_assert<'a>(value: &'a TypedExpr, pat: &'a TypedPattern, env: &mut Env<'a> line(), erlang_error( "let_assert", - &string("Assertion pattern match failed"), + &string("Pattern match failed, no pattern matched the value."), pat.location(), vec![("value", env.local_var_name(ASSERT_FAIL_VARIABLE))], env, @@ -1063,27 +1095,39 @@ fn var<'a>(name: &'a str, constructor: &'a ValueConstructor, env: &mut Env<'a>) ValueConstructorVariant::ModuleConstant { literal, .. } | ValueConstructorVariant::LocalConstant { literal } => const_inline(literal, env), + ValueConstructorVariant::ModuleFn { + arity, + external_erlang: Some((module, name)), + .. + } if module == env.module => function_reference(None, name, *arity), + + ValueConstructorVariant::ModuleFn { + arity, + external_erlang: Some((module, name)), + .. + } => function_reference(Some(module), name, *arity), + ValueConstructorVariant::ModuleFn { arity, ref module, .. - } if module == env.module => "fun " - .to_doc() - .append(atom(escape_erlang_existing_name(name))) - .append("/") - .append(*arity), + } if module == env.module => function_reference(None, name, *arity), ValueConstructorVariant::ModuleFn { arity, module, name, .. - } => "fun " - .to_doc() - .append(module_name_atom(module)) - .append(":") - .append(atom(escape_erlang_existing_name(name))) - .append("/") - .append(*arity), + } => function_reference(Some(module), name, *arity), + } +} + +fn function_reference<'a>(module: Option<&'a str>, name: &'a str, arity: usize) -> Document<'a> { + match module { + None => "fun ".to_doc(), + Some(module) => "fun ".to_doc().append(module_name_atom(module)).append(":"), } + .append(atom(escape_erlang_existing_name(name))) + .append("/") + .append(arity) } fn int<'a>(value: &str) -> Document<'a> { @@ -1120,7 +1164,9 @@ fn const_inline<'a>(literal: &'a TypedConstant, env: &mut Env<'a>) -> Document<' .map(|s| const_segment(&s.value, &s.options, env)), ), - Constant::Record { tag, typ, args, .. } if args.is_empty() => match typ.deref() { + Constant::Record { + tag, type_, args, .. + } if args.is_empty() => match type_.deref() { Type::Fn { args, .. } => record_constructor_function(tag, args.len()), _ => atom_string(tag.to_snake_case()), }, @@ -1480,7 +1526,12 @@ fn docs_args_call<'a>( TypedExpr::Var { constructor: ValueConstructor { - variant: ValueConstructorVariant::ModuleFn { module, name, .. }, + variant: + ValueConstructorVariant::ModuleFn { + external_erlang: Some((module, name)), + .. + } + | ValueConstructorVariant::ModuleFn { module, name, .. }, .. }, .. @@ -1505,7 +1556,12 @@ fn docs_args_call<'a>( }, .. } if constructor.variant.is_module_fn() => { - if let ValueConstructorVariant::ModuleFn { module, name, .. } = &constructor.variant { + if let ValueConstructorVariant::ModuleFn { + external_erlang: Some((module, name)), + .. + } + | ValueConstructorVariant::ModuleFn { module, name, .. } = &constructor.variant + { module_fn_with_args(module, name, args, env) } else { unreachable!("The above clause guard ensures that this is a module fn") @@ -1513,7 +1569,12 @@ fn docs_args_call<'a>( } TypedExpr::ModuleSelect { - constructor: ModuleValueConstructor::Fn { module, name, .. }, + constructor: + ModuleValueConstructor::Fn { + external_erlang: Some((module, name)), + .. + } + | ModuleValueConstructor::Fn { module, name, .. }, .. } => { let args = wrap_args(args); @@ -1639,7 +1700,7 @@ fn needs_begin_end_wrapping(expression: &TypedExpr) -> bool { fn todo<'a>(message: Option<&'a TypedExpr>, location: SrcSpan, env: &mut Env<'a>) -> Document<'a> { let message = match message { Some(m) => expr(m, env), - None => string("This has not yet been implemented"), + None => string("`todo` expression evaluated. This code has not yet been implemented."), }; erlang_error("todo", &message, location, vec![], env) } @@ -1647,7 +1708,7 @@ fn todo<'a>(message: Option<&'a TypedExpr>, location: SrcSpan, env: &mut Env<'a> fn panic<'a>(location: SrcSpan, message: Option<&'a TypedExpr>, env: &mut Env<'a>) -> Document<'a> { let message = match message { Some(m) => expr(m, env), - None => string("panic expression evaluated"), + None => string("`panic` expression evaluated."), }; erlang_error("panic", &message, location, vec![], env) } @@ -1752,10 +1813,15 @@ fn expr<'a>(expression: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> { } => record_constructor_function(name, *arity as usize), TypedExpr::ModuleSelect { - typ, - constructor: ModuleValueConstructor::Fn { module, name, .. }, + type_, + constructor: + ModuleValueConstructor::Fn { + external_erlang: Some((module, name)), + .. + } + | ModuleValueConstructor::Fn { module, name, .. }, .. - } => module_select_fn(typ.clone(), module, name), + } => module_select_fn(type_.clone(), module, name), TypedExpr::RecordAccess { record, index, .. } => tuple_index(record, index + 1, env), @@ -1782,7 +1848,7 @@ fn expr<'a>(expression: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> { } fn pipeline<'a>( - assignments: &'a [Assignment, TypedExpr>], + assignments: &'a [TypedAssignment], finally: &'a TypedExpr, env: &mut Env<'a>, ) -> Document<'a> { @@ -1817,8 +1883,8 @@ fn tuple_index<'a>(tuple: &'a TypedExpr, index: u64, env: &mut Env<'a>) -> Docum .append(wrap_args([index_doc, tuple_doc])) } -fn module_select_fn<'a>(typ: Arc, module_name: &'a str, label: &'a str) -> Document<'a> { - match crate::type_::collapse_links(typ).as_ref() { +fn module_select_fn<'a>(type_: Arc, module_name: &'a str, label: &'a str) -> Document<'a> { + match crate::type_::collapse_links(type_).as_ref() { Type::Fn { args, .. } => "fun " .to_doc() .append(module_name_to_erlang(module_name)) @@ -2012,8 +2078,8 @@ fn collect_type_var_usages<'a>( mut ids: HashMap, types: impl IntoIterator>, ) -> HashMap { - for typ in types { - type_var_ids(typ, &mut ids); + for type_ in types { + type_var_ids(type_, &mut ids); } ids } @@ -2048,12 +2114,12 @@ fn result_type_var_ids(ids: &mut HashMap, arg_ok: &Type, arg_err: &Typ fn type_var_ids(type_: &Type, ids: &mut HashMap) { match type_ { - Type::Var { type_: typ } => match typ.borrow().deref() { + Type::Var { type_ } => match type_.borrow().deref() { TypeVar::Generic { id, .. } | TypeVar::Unbound { id, .. } => { let count = ids.entry(*id).or_insert(0); *count += 1; } - TypeVar::Link { type_: typ } => type_var_ids(typ, ids), + TypeVar::Link { type_ } => type_var_ids(type_, ids), }, Type::Named { args, module, name, .. @@ -2153,7 +2219,7 @@ impl<'a> TypePrinter<'a> { pub fn print(&self, type_: &Type) -> Document<'static> { match type_ { - Type::Var { type_: typ } => self.print_var(&typ.borrow()), + Type::Var { type_ } => self.print_var(&type_.borrow()), Type::Named { name, module, args, .. @@ -2182,7 +2248,7 @@ impl<'a> TypePrinter<'a> { }, None => id_to_type_var(*id), }, - TypeVar::Link { type_: typ } => self.print(typ), + TypeVar::Link { type_ } => self.print(type_), } } diff --git a/compiler-core/src/erlang/pattern.rs b/compiler-core/src/erlang/pattern.rs index a396212a8..30eb6b008 100644 --- a/compiler-core/src/erlang/pattern.rs +++ b/compiler-core/src/erlang/pattern.rs @@ -192,15 +192,23 @@ fn pattern_segment<'a>( env: &mut Env<'a>, guards: &mut Vec>, ) -> Document<'a> { + let mut pattern_is_a_string_literal = false; + let mut pattern_is_a_discard = false; let document = match value { // Skip the normal <> surrounds - Pattern::String { value, .. } => value.to_doc().surround("\"", "\""), + Pattern::String { value, .. } => { + pattern_is_a_string_literal = true; + value.to_doc().surround("\"", "\"") + } // As normal - Pattern::Discard { .. } - | Pattern::Variable { .. } - | Pattern::Int { .. } - | Pattern::Float { .. } => print(value, vars, define_variables, env, guards), + Pattern::Discard { .. } => { + pattern_is_a_discard = true; + print(value, vars, define_variables, env, guards) + } + Pattern::Variable { .. } | Pattern::Int { .. } | Pattern::Float { .. } => { + print(value, vars, define_variables, env, guards) + } // No other pattern variants are allowed in pattern bit array segments _ => panic!("Pattern segment match not recognised"), @@ -215,7 +223,15 @@ fn pattern_segment<'a>( let unit = |value: &'a u8| Some(Document::String(format!("unit:{value}"))); - bit_array_segment(document, options, size, unit, true, env) + bit_array_segment( + document, + options, + size, + unit, + pattern_is_a_string_literal, + pattern_is_a_discard, + env, + ) } fn pattern_list<'a>( diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__allowed_string_escapes.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__allowed_string_escapes.snap index cf72c548d..5f7173254 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__allowed_string_escapes.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__allowed_string_escapes.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 488 expression: "pub fn a() { \"\\n\" \"\\r\" \"\\t\" \"\\\\\" \"\\\"\" \"\\\\^\" }" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn a() { \"\\n\" \"\\r\" \"\\t\" \"\\\\\" \"\\\"\" \"\\\\^\" }" -export([a/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec a() -> binary(). a() -> <<"\n"/utf8>>, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__binop_parens.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__binop_parens.snap index 75b3dd779..41210c711 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__binop_parens.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__binop_parens.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 382 expression: "\npub fn main() {\n let a = 2 * {3 + 1} / 2\n let b = 5 + 3 / 3 * 2 - 6 * 4\n b\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let a = 2 * {3 + 1} / 2\n let b = 5 + 3 / -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> A = (2 * (3 + 1)) div 2, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__block_assignment.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__block_assignment.snap index d760be6db..00bffd122 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__block_assignment.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__block_assignment.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 426 expression: "\npub fn main() {\n let x = {\n 1\n 2\n }\n x\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let x = {\n 1\n 2\n }\n x\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> X = begin diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info.snap index d7905a603..f2885ecee 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 744 expression: "\npub const module_info = 1\n\npub fn main() {\n module_info\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub const module_info = 1\n\npub fn main() {\n module_info\n}\ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> integer(). main() -> 1. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_imported.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_imported.snap index 7c305c4dd..561ffd16c 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_imported.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_imported.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 758 expression: "\nimport some_module\n\npub fn main() {\n some_module.module_info\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some_module\n\npub fn main() {\n some_module.module_inf -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> integer(). main() -> 1. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_imported_qualified.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_imported_qualified.snap index 9d80af606..9836783cb 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_imported_qualified.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_imported_qualified.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 779 expression: "\nimport some_module.{module_info}\n\npub fn main() {\n module_info\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some_module.{module_info}\n\npub fn main() {\n module_i -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> integer(). main() -> 1. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside.snap index ca177214d..caf601e8e 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 800 expression: "\npub fn function() {\n 1\n}\n\npub const module_info = function\n\npub fn main() {\n module_info()\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\npub fn function() {\n 1\n}\n\npub const module_info = function -export([function/0, main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec function() -> integer(). function() -> 1. +-file("/root/project/test/my/mod.gleam", 8). -spec main() -> integer(). main() -> function(). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside_imported.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside_imported.snap index 47b3bc232..e38008de0 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside_imported.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside_imported.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 818 expression: "\nimport some_module\n\npub fn main() {\n some_module.module_info()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some_module\n\npub fn main() {\n some_module.module_inf -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> integer(). main() -> fun some_module:function/0(). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside_imported_qualified.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside_imported_qualified.snap index 016e9a0fe..ccbc7b362 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside_imported_qualified.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__constant_named_module_info_with_function_inside_imported_qualified.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 843 expression: "\nimport some_module.{module_info}\n\npub fn main() {\n module_info()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some_module.{module_info}\n\npub fn main() {\n module_i -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> integer(). main() -> some_module:function(). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__discard_in_assert.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__discard_in_assert.snap index f75e1762c..e8c500fea 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__discard_in_assert.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__discard_in_assert.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 505 expression: "pub fn x(y) {\n let assert Ok(_) = y\n 1\n}" --- -module(my@mod). @@ -7,13 +8,14 @@ expression: "pub fn x(y) {\n let assert Ok(_) = y\n 1\n}" -export([x/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec x({ok, any()} | {error, any()}) -> integer(). x(Y) -> {ok, _} = case Y of {ok, _} -> Y; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"x"/utf8>>, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__field_access_function_call.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__field_access_function_call.snap index 3a0097b4e..a083088a4 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__field_access_function_call.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__field_access_function_call.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 396 expression: "\ntype FnBox {\n FnBox(f: fn(Int) -> Int)\n}\nfn main() {\n let b = FnBox(f: fn(x) { x })\n b.f(5)\n}\n" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "\ntype FnBox {\n FnBox(f: fn(Int) -> Int)\n}\nfn main() {\n let -type fn_box() :: {fn_box, fun((integer()) -> integer())}. +-file("/root/project/test/my/mod.gleam", 5). -spec main() -> integer(). main() -> B = {fn_box, fun(X) -> X end}, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__field_access_function_call1.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__field_access_function_call1.snap index 0dad35008..edbfd4fba 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__field_access_function_call1.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__field_access_function_call1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 412 expression: "\npub fn main() {\n let t = #(fn(x) { x })\n\n t.0(5)\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let t = #(fn(x) { x })\n\n t.0(5)\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> T = {fun(X) -> X end}, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_argument_shadowing.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_argument_shadowing.snap index 7c7e2449f..c8e92224f 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_argument_shadowing.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_argument_shadowing.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 586 expression: "pub fn main(a) {\n Box\n}\n\npub type Box {\n Box(Int)\n}\n" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "pub fn main(a) {\n Box\n}\n\npub type Box {\n Box(Int)\n}\n" -type box() :: {box, integer()}. +-file("/root/project/test/my/mod.gleam", 1). -spec main(any()) -> fun((integer()) -> box()). main(A) -> fun(Field@0) -> {box, Field@0} end. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info.snap index f918886d8..ff246dde5 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 682 expression: "\npub fn module_info() {\n 1\n}\n\npub fn main() {\n module_info()\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\npub fn module_info() {\n 1\n}\n\npub fn main() {\n module_i -export(['moduleInfo'/0, main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec 'moduleInfo'() -> integer(). 'moduleInfo'() -> 1. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> integer(). main() -> 'moduleInfo'(). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_imported.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_imported.snap index 644318015..4f5d91b28 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_imported.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_imported.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 698 expression: "\nimport some_module\n\npub fn main() {\n some_module.module_info()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some_module\n\npub fn main() {\n some_module.module_inf -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> integer(). main() -> some_module:'moduleInfo'(). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_imported_qualified.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_imported_qualified.snap index 263e330fb..59bd48acf 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_imported_qualified.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_imported_qualified.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 721 expression: "\nimport some_module.{module_info}\n\npub fn main() {\n module_info()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some_module.{module_info}\n\npub fn main() {\n module_i -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> integer(). main() -> some_module:'moduleInfo'(). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant.snap index 88c1d694c..4d1430119 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 868 expression: "\npub fn module_info() {\n 1\n}\n\npub const constant = module_info\n\npub fn main() {\n constant()\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\npub fn module_info() {\n 1\n}\n\npub const constant = module_i -export(['moduleInfo'/0, main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec 'moduleInfo'() -> integer(). 'moduleInfo'() -> 1. +-file("/root/project/test/my/mod.gleam", 8). -spec main() -> integer(). main() -> 'moduleInfo'(). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant_imported.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant_imported.snap index 2e9284ae0..5f393fc0d 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant_imported.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant_imported.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 886 expression: "\nimport some_module\n\npub fn main() {\n some_module.constant()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some_module\n\npub fn main() {\n some_module.constant() -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> integer(). main() -> fun some_module:'moduleInfo'/0(). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant_imported_qualified.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant_imported_qualified.snap index 0effb643a..8cde7fe59 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant_imported_qualified.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__function_named_module_info_in_constant_imported_qualified.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 911 expression: "\nimport some_module.{constant}\n\npub fn main() {\n constant()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some_module.{constant}\n\npub fn main() {\n constant()\ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> integer(). main() -> some_module:'moduleInfo'(). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__guard_variable_rewriting.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__guard_variable_rewriting.snap index e0bd20323..f9c2f9bd4 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__guard_variable_rewriting.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__guard_variable_rewriting.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 569 expression: "pub fn main() {\n case 1.0 {\n a if a <. 0.0 -> {\n let a = a\n a\n }\n _ -> 0.0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn main() {\n case 1.0 {\n a if a <. 0.0 -> {\n let a -export([main/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec main() -> float(). main() -> case 1.0 of diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__inline_const_pattern_option.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__inline_const_pattern_option.snap index 0493a5f85..b5605eac5 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__inline_const_pattern_option.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__inline_const_pattern_option.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 607 expression: "pub fn main() {\n let fifteen = 15\n let x = <<5:size(sixteen)>>\n case x {\n <<5:size(sixteen)>> -> <<5:size(sixteen)>>\n <<6:size(fifteen)>> -> <<5:size(fifteen)>>\n _ -> <<>>\n }\n }\n\n pub const sixteen = 16" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn main() {\n let fifteen = 15\n let x = -export([main/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec main() -> bitstring(). main() -> Fifteen = 15, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test.snap index 4d99d183b..8aa0099c9 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 118 expression: "pub fn go() {\nlet x = #(100000000000000000, #(2000000000, 3000000000000, 40000000000), 50000, 6000000000)\n x\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn go() {\nlet x = #(100000000000000000, #(2000000000, 30000000 -export([go/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec go() -> {integer(), {integer(), integer(), integer()}, integer(), diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_1.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_1.snap index 68a33cd20..22a501175 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_1.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 128 expression: "pub fn go() {\n let y = 1\n let y = 2\n y\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn go() {\n let y = 1\n let y = 2\n y\n}" -export([go/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec go() -> integer(). go() -> Y = 1, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_2.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_2.snap index f0f52eb26..3d208d800 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_2.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 140 expression: "pub fn go() {\n let fifteen = 0xF\n let nine = 0o11\n let ten = 0b1010\n fifteen\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn go() {\n let fifteen = 0xF\n let nine = 0o11\n let -export([go/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec go() -> integer(). go() -> Fifteen = 16#F, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_3.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_3.snap index 68a33cd20..9117a2db2 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_3.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test0_3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 152 expression: "pub fn go() {\n let y = 1\n let y = 2\n y\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn go() {\n let y = 1\n let y = 2\n y\n}" -export([go/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec go() -> integer(). go() -> Y = 1, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1.snap index f6b109054..1914747da 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 163 expression: "pub fn t() { True }" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn t() { True }" -export([t/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec t() -> boolean(). t() -> true. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test10.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test10.snap index 59e606ec9..a136178fe 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test10.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test10.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 248 expression: "type Null { Null } fn x() { Null }" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "type Null { Null } fn x() { Null }" -type null() :: null. +-file("/root/project/test/my/mod.gleam", 1). -spec x() -> null(). x() -> null. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test11.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test11.snap index 3d1ad7fd3..646f9d511 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test11.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test11.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 261 expression: "type Point { Point(x: Int, y: Int) }\n fn x() { Point(x: 4, y: 6) Point(y: 1, x: 9) }" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "type Point { Point(x: Int, y: Int) }\n fn x() { Poin -type point() :: {point, integer(), integer()}. +-file("/root/project/test/my/mod.gleam", 2). -spec x() -> point(). x() -> {point, 4, 6}, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test12.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test12.snap index 1330dce80..af67326c6 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test12.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test12.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 269 expression: "type Point { Point(x: Int, y: Int) } fn x(y) { let Point(a, b) = y a }" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "type Point { Point(x: Int, y: Int) } fn x(y) { let Point(a, b) = y -type point() :: {point, integer(), integer()}. +-file("/root/project/test/my/mod.gleam", 1). -spec x(point()) -> integer(). x(Y) -> {point, A, B} = Y, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test13.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test13.snap index edcea0af5..792063daa 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test13.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test13.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 275 expression: "pub type State{ Start(Int) End(Int) }\n pub fn build(constructor : fn(Int) -> a) -> a { constructor(1) }\n pub fn main() { build(End) }" --- -module(my@mod). @@ -10,10 +11,12 @@ expression: "pub type State{ Start(Int) End(Int) }\n pub fn build(con -type state() :: {start, integer()} | {'end', integer()}. +-file("/root/project/test/my/mod.gleam", 2). -spec build(fun((integer()) -> I)) -> I. build(Constructor) -> Constructor(1). +-file("/root/project/test/my/mod.gleam", 3). -spec main() -> state(). main() -> build(fun(Field@0) -> {'end', Field@0} end). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test16.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test16.snap index 7170bd072..92e4d87de 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test16.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test16.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 284 expression: "fn go(x xx, y yy) { xx }\npub fn x() { go(x: 1, y: 2) go(y: 3, x: 4) }" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "fn go(x xx, y yy) { xx }\npub fn x() { go(x: 1, y: 2) go(y: 3, x: 4 -export([x/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec go(I, any()) -> I. go(Xx, Yy) -> Xx. +-file("/root/project/test/my/mod.gleam", 2). -spec x() -> integer(). x() -> go(1, 2), diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test17.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test17.snap index fe1d4c9f1..d4d944621 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test17.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test17.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 293 expression: "\ntype User { User(id: Int, name: String, age: Int) }\nfn create_user(user_id) { User(age: 22, id: user_id, name: \"\") }\n " --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "\ntype User { User(id: Int, name: String, age: Int) }\nfn create_us -type user() :: {user, integer(), binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 3). -spec create_user(integer()) -> user(). create_user(User_id) -> {user, User_id, <<""/utf8>>, 22}. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test18.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test18.snap index 054459489..5a3fa1b79 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test18.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test18.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 303 expression: "pub fn run() { case 1, 2 { a, b -> a } }" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn run() { case 1, 2 { a, b -> a } }" -export([run/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec run() -> integer(). run() -> case {1, 2} of diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test19.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test19.snap index 263ddfe2d..bb5dabcb4 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test19.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test19.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 308 expression: "type X { X(x: Int, y: Float) }\n fn x() { X(x: 1, y: 2.) X(y: 3., x: 4) }" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "type X { X(x: Int, y: Float) }\n fn x() { X(x: 1 -type x() :: {x, integer(), float()}. +-file("/root/project/test/my/mod.gleam", 2). -spec x() -> x(). x() -> {x, 1, 2.0}, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_1.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_1.snap index fe7706638..917c5e251 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_1.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 168 expression: "pub type Money { Pound(Int) }\n fn pound(x) { Pound(x) }" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "pub type Money { Pound(Int) }\n fn pound(x) { Po -type money() :: {pound, integer()}. +-file("/root/project/test/my/mod.gleam", 2). -spec pound(integer()) -> money(). pound(X) -> {pound, X}. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_2.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_2.snap index 6a216d5c6..9df950bf8 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_2.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 176 expression: "pub fn loop() { loop() }" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn loop() { loop() }" -export([loop/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec loop() -> any(). loop() -> loop(). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_4.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_4.snap index 8cf766bfd..db14e76e4 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_4.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_4.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 181 expression: "fn inc(x) { x + 1 }\n pub fn go() { 1 |> inc |> inc |> inc }" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "fn inc(x) { x + 1 }\n pub fn go() { 1 |> inc |> -export([go/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec inc(integer()) -> integer(). inc(X) -> X + 1. +-file("/root/project/test/my/mod.gleam", 2). -spec go() -> integer(). go() -> _pipe = 1, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_5.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_5.snap index 130a86df5..1c0d5f40c 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_5.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_5.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 189 expression: "fn add(x, y) { x + y }\n pub fn go() { 1 |> add(_, 1) |> add(2, _) |> add(_, 3) }" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "fn add(x, y) { x + y }\n pub fn go() { 1 |> add( -export([go/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec add(integer(), integer()) -> integer(). add(X, Y) -> X + Y. +-file("/root/project/test/my/mod.gleam", 2). -spec go() -> integer(). go() -> _pipe = 1, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_6.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_6.snap index b5c74e360..c4847dc24 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_6.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test1_6.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 197 expression: "pub fn and(x, y) { x && y }\npub fn or(x, y) { x || y }\npub fn remainder(x, y) { x % y }\npub fn fdiv(x, y) { x /. y }\n " --- -module(my@mod). @@ -7,14 +8,17 @@ expression: "pub fn and(x, y) { x && y }\npub fn or(x, y) { x || y }\npub fn rem -export(['and'/2, 'or'/2, remainder/2, fdiv/2]). +-file("/root/project/test/my/mod.gleam", 1). -spec 'and'(boolean(), boolean()) -> boolean(). 'and'(X, Y) -> X andalso Y. +-file("/root/project/test/my/mod.gleam", 2). -spec 'or'(boolean(), boolean()) -> boolean(). 'or'(X, Y) -> X orelse Y. +-file("/root/project/test/my/mod.gleam", 3). -spec remainder(integer(), integer()) -> integer(). remainder(X, Y) -> case Y of @@ -22,6 +26,7 @@ remainder(X, Y) -> Gleam@denominator -> X rem Gleam@denominator end. +-file("/root/project/test/my/mod.gleam", 4). -spec fdiv(float(), float()) -> float(). fdiv(X, Y) -> case Y of diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test2.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test2.snap index 0e3dcbe2f..8b9efe5ed 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test2.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 208 expression: "pub fn second(list) { case list { [x, y] -> y z -> 1 } }\npub fn tail(list) { case list { [x, ..xs] -> xs z -> list } }\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn second(list) { case list { [x, y] -> y z -> 1 } }\npub fn ta -export([second/1, tail/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec second(list(integer())) -> integer(). second(List) -> case List of @@ -17,6 +19,7 @@ second(List) -> 1 end. +-file("/root/project/test/my/mod.gleam", 2). -spec tail(list(P)) -> list(P). tail(List) -> case List of diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test20.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test20.snap index d61fbd06c..b38f88b9d 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test20.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test20.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 316 expression: "\npub fn go(a) {\n let a = a + 1\n a\n}\n\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(a) {\n let a = a + 1\n a\n}\n\n " -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(integer()) -> integer(). go(A) -> A@1 = A + 1, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test21.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test21.snap index d33f36fa1..270eb6cce 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test21.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test21.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 329 expression: "\npub fn go(a) {\n let a = 1\n a\n}\n\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(a) {\n let a = 1\n a\n}\n\n " -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(any()) -> integer(). go(A) -> A@1 = 1, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test22.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test22.snap index 0fd75af05..2bcfd32d1 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test22.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test22.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 343 expression: "\npub fn factory(f, i) {\n f(i)\n}\n\npub type Box {\n Box(i: Int)\n}\n\npub fn main() {\n factory(Box, 0)\n}\n" --- -module(my@mod). @@ -10,10 +11,12 @@ expression: "\npub fn factory(f, i) {\n f(i)\n}\n\npub type Box {\n Box(i: Int -type box() :: {box, integer()}. +-file("/root/project/test/my/mod.gleam", 2). -spec factory(fun((J) -> N), J) -> N. factory(F, I) -> F(I). +-file("/root/project/test/my/mod.gleam", 10). -spec main() -> box(). main() -> factory(fun(Field@0) -> {box, Field@0} end, 0). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test23.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test23.snap index e529296c9..e7f34d25e 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test23.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test23.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 363 expression: "\npub fn main(args) {\n case args {\n _ -> {\n let a = 1\n a\n }\n }\n let a = 2\n a\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(args) {\n case args {\n _ -> {\n let a = 1\n -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(any()) -> integer(). main(Args) -> case Args of diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test3.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test3.snap index c599fd2bb..18a2562e1 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test3.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 253 expression: "type Point { Point(x: Int, y: Int) }\n fn y() { fn() { Point }()(4, 6) }" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "type Point { Point(x: Int, y: Int) }\n fn y() { fn() -type point() :: {point, integer(), integer()}. +-file("/root/project/test/my/mod.gleam", 2). -spec y() -> point(). y() -> ((fun() -> fun(Field@0, Field@1) -> {point, Field@0, Field@1} end end)())( diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test5.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test5.snap index d35f7ed75..70be61b2a 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test5.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test5.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 217 expression: "pub fn tail(list) {\n case list {\n [x, ..] -> x\n _ -> 0\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn tail(list) {\n case list {\n [x, ..] -> x\n _ -> 0\n -export([tail/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec tail(list(integer())) -> integer(). tail(List) -> case List of diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test6.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test6.snap index d293afd36..6c5d6da66 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test6.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test6.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 229 expression: "pub fn x() { let x = 1 let x = x + 1 x }" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn x() { let x = 1 let x = x + 1 x }" -export([x/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec x() -> integer(). x() -> X = 1, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test8.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test8.snap index 4d7b979e5..a1669f66e 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test8.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test8.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 235 expression: "pub fn x() { 1. <. 2.3 }" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn x() { 1. <. 2.3 }" -export([x/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec x() -> boolean(). x() -> 1.0 < 2.3. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test9.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test9.snap index ddfa98ab8..95df7f376 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test9.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__integration_test9.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 241 expression: "pub type Pair(x, y) { Pair(x: x, y: y) } pub fn x() { Pair(1, 2) Pair(3., 4.) }" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "pub type Pair(x, y) { Pair(x: x, y: y) } pub fn x() { Pair(1, 2) Pa -type pair(I, J) :: {pair, I, J}. +-file("/root/project/test/my/mod.gleam", 1). -spec x() -> pair(float(), float()). x() -> {pair, 1, 2}, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__negation.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__negation.snap index 2cd9a92cc..8c6b09b32 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__negation.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__negation.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 529 expression: "pub fn negate(x) {\n !x\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn negate(x) {\n !x\n}" -export([negate/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec negate(boolean()) -> boolean(). negate(X) -> not X. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__negation_block.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__negation_block.snap index 71497d5e7..2f5e37006 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__negation_block.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__negation_block.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 538 expression: "pub fn negate(x) {\n !{\n 123\n x\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn negate(x) {\n !{\n 123\n x\n }\n}" -export([negate/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec negate(boolean()) -> boolean(). negate(X) -> not begin diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__operator_pipe_right_hand_side.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__operator_pipe_right_hand_side.snap index 1f5fdf495..ed5a8cf30 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__operator_pipe_right_hand_side.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__operator_pipe_right_hand_side.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 516 expression: "fn id(x) {\n x\n}\n\npub fn bool_expr(x, y) {\n y || x |> id\n}" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "fn id(x) {\n x\n}\n\npub fn bool_expr(x, y) {\n y || x |> id\n}" -export([bool_expr/2]). +-file("/root/project/test/my/mod.gleam", 1). -spec id(I) -> I. id(X) -> X. +-file("/root/project/test/my/mod.gleam", 5). -spec bool_expr(boolean(), boolean()) -> boolean(). bool_expr(X, Y) -> Y orelse begin diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__positive_zero.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__positive_zero.snap index 420291d76..3ec9edba0 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__positive_zero.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__positive_zero.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 625 expression: "\npub fn main() {\n 0.0\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n 0.0\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> float(). main() -> +0.0. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__recursive_type.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__recursive_type.snap index c8ac09ae8..2c05ae54f 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__recursive_type.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__recursive_type.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 444 expression: "\nfn id(x) {\n x\n}\n\npub fn main() {\n id(id)\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\nfn id(x) {\n x\n}\n\npub fn main() {\n id(id)\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec id(I) -> I. id(X) -> X. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> fun((M) -> M). main() -> id(fun id/1). diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__scientific_notation.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__scientific_notation.snap index cdf9b7386..3e79ae257 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__scientific_notation.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__scientific_notation.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 637 expression: "\npub fn main() {\n 1.0e6\n 1.e6\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n 1.0e6\n 1.e6\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> float(). main() -> 1.0e6, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__tail_maybe_expr_block.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__tail_maybe_expr_block.snap index e6196a852..061423fb3 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__tail_maybe_expr_block.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__tail_maybe_expr_block.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 551 expression: "pub fn a() {\n let fake_tap = fn(x) { x }\n let b = [99]\n [\n 1,\n 2,\n ..b\n |> fake_tap\n ]\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn a() {\n let fake_tap = fn(x) { x }\n let b = [99]\n [\n -export([a/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec a() -> list(integer()). a() -> Fake_tap = fun(X) -> X end, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__tuple_access_in_guard.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__tuple_access_in_guard.snap index d6b975e09..43861ba4f 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__tuple_access_in_guard.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__tuple_access_in_guard.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 459 expression: "\npub fn main() {\n let key = 10\n let x = [#(10, 2), #(1, 2)]\n case x {\n [first, ..rest] if first.0 == key -> \"ok\"\n _ -> \"ko\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let key = 10\n let x = [#(10, 2), #(1, 2) -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> binary(). main() -> Key = 10, diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__type_named_else.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__type_named_else.snap index 3a505aaa1..9b0161fd9 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__type_named_else.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__type_named_else.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 650 expression: "\npub type Else {\n Else\n}\n\npub fn main() {\n Else\n}\n" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\npub type Else {\n Else\n}\n\npub fn main() {\n Else\n}\n" -type 'else'() :: 'else'. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> 'else'(). main() -> 'else'. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__type_named_module_info.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__type_named_module_info.snap index a05426ec8..34ac8e82d 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__type_named_module_info.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__type_named_module_info.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 666 expression: "\npub type ModuleInfo {\n ModuleInfo\n}\n\npub fn main() {\n ModuleInfo\n}\n" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\npub type ModuleInfo {\n ModuleInfo\n}\n\npub fn main() {\n -type module_info() :: module_info. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> module_info(). main() -> module_info. diff --git a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__variable_name_underscores_preserved.snap b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__variable_name_underscores_preserved.snap index 42aca56a3..ab8d62886 100644 --- a/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__variable_name_underscores_preserved.snap +++ b/compiler-core/src/erlang/snapshots/glistix_core__erlang__tests__variable_name_underscores_preserved.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests.rs +assertion_line: 475 expression: "pub fn a(name_: String) -> String {\n let name__ = name_\n let name = name__\n let one_1 = 1\n let one1 = one_1\n name\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn a(name_: String) -> String {\n let name__ = name_\n le -export([a/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec a(binary()) -> binary(). a(Name_) -> Name__ = Name_, diff --git a/compiler-core/src/erlang/tests.rs b/compiler-core/src/erlang/tests.rs index b1daa2c09..ade270e7e 100644 --- a/compiler-core/src/erlang/tests.rs +++ b/compiler-core/src/erlang/tests.rs @@ -73,9 +73,9 @@ pub fn compile_test_project(src: &str, dep: Option<(&str, &str, &str)>) -> Strin let _ = modules.insert(dep_name.into(), dep.type_info); let _ = direct_dependencies.insert(dep_package.into(), ()); } - let parsed = - crate::parse::parse_module(Utf8PathBuf::from("test/path"), src, &WarningEmitter::null()) - .expect("syntax error"); + let path = Utf8PathBuf::from("/root/project/test/my/mod.gleam"); + let parsed = crate::parse::parse_module(path.clone(), src, &WarningEmitter::null()) + .expect("syntax error"); let mut config = PackageConfig::default(); config.name = "thepackage".into(); let mut ast = parsed.module; @@ -91,7 +91,7 @@ pub fn compile_test_project(src: &str, dep: Option<(&str, &str, &str)>) -> Strin target_support: TargetSupport::NotEnforced, package_config: &config, } - .infer_module(ast, line_numbers, "".into()) + .infer_module(ast, line_numbers, path) .expect("should successfully infer root Erlang"); let line_numbers = LineNumbers::new(src); module(&ast, &line_numbers).unwrap() diff --git a/compiler-core/src/erlang/tests/bit_arrays.rs b/compiler-core/src/erlang/tests/bit_arrays.rs index 31bdc1aaf..048a8d5a0 100644 --- a/compiler-core/src/erlang/tests/bit_arrays.rs +++ b/compiler-core/src/erlang/tests/bit_arrays.rs @@ -22,7 +22,7 @@ fn bit_array_float() { r#"pub fn main() { let b = 16 let floats = <<1.0:16-float, 5.0:float-32, 6.0:float-64-little, 1.0:float-size(b)>> - let assert <<1.0:16-float, 5.0:float-32, 6.0:float-64-little, 1.0:float-size(b)>> = floats + let assert <<1.0:16-float, 5.0:float-32, 6.0:float-64-little, 1.0:float-size(b)>> = floats }"# ); } @@ -161,3 +161,46 @@ fn unicode_bit_array_2() { }"# ); } + +#[test] +fn bit_array_literal_string_constant_is_treated_as_utf8() { + assert_erl!( + r#" +const a = <<"hello", " ", "world">> +pub fn main() { a } +"# + ); +} + +#[test] +fn bit_array_literal_string_is_treated_as_utf8() { + assert_erl!( + r#" +pub fn main() { + <<"hello", " ", "world">> +}"# + ); +} + +#[test] +fn bit_array_literal_string_pattern_is_treated_as_utf8() { + assert_erl!( + r#" +pub fn main() { + case <<>> { + <<"a", "b", _:bits>> -> 1 + _ -> 2 + } +}"# + ); +} + +#[test] +fn discard_utf8_pattern() { + assert_erl!( + r#" +pub fn main() { + let assert <<_:utf8, rest:bits>> = <<>> +}"# + ); +} diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array.snap index 2a2a135e6..5ac3d7a20 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 5 expression: "pub fn main() {\n let a = 1\n let simple = <<1, a>>\n let complex = <<4:int-big, 5.0:little-float, 6:native-int>>\n let assert <<7:2, 8:size(3), b:bytes-size(4)>> = <<1>>\n let assert <> = <<1>>\n\n simple\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn main() {\n let a = 1\n let simple = <<1, a>>\n let comple -export([main/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec main() -> bitstring(). main() -> A = 1, @@ -17,7 +19,7 @@ main() -> <<7:2, 8:3, _:4/binary>> -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, @@ -28,7 +30,7 @@ main() -> <<_:8/unit:1, _:2/binary-unit:2>> -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail@1, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array1.snap index c640a53d9..cd15c33ab 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 32 expression: "pub fn x() { 2 }\nfn main() {\n let a = -1\n let b = <>\n\n b\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "pub fn x() { 2 }\nfn main() {\n let a = -1\n let b = < integer(). x() -> 2. +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> bitstring(). main() -> A = -1, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array2.snap index 69a3764e3..a71c3858c 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 46 expression: "pub fn main() {\n let a = 1\n let assert <> = <<1, a>>\n b\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn main() {\n let a = 1\n let assert <> = <<1, a>>\n b -export([main/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec main() -> integer(). main() -> A = 1, @@ -15,7 +17,7 @@ main() -> <<_, 1>> -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array3.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array3.snap index 65078aa42..1467b0779 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array3.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 58 expression: "pub fn main() {\n let a = <<\"test\":utf8>>\n let assert <> = a\n b\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn main() {\n let a = <<\"test\":utf8>>\n let assert < integer(). main() -> A = <<"test"/utf8>>, @@ -14,7 +16,7 @@ main() -> <<_/utf8, "st"/utf8>> -> A; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array4.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array4.snap index 31bf1e915..e2b158bdf 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array4.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array4.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 70 expression: "fn x() { 1 }\npub fn main() {\n let a = <>\n a\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "fn x() { 1 }\npub fn main() {\n let a = <>\n a\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec x() -> integer(). x() -> 1. +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> bitstring(). main() -> A = <<(x())/integer>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array5.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array5.snap index feeedf977..b96a09d8d 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array5.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array5.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 82 expression: "const bit_size = 8\npub fn main() {\n let a = <<10:size(bit_size)>>\n a\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "const bit_size = 8\npub fn main() {\n let a = <<10:size(bit_size)> -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> bitstring(). main() -> A = <<10:(lists:max([(8), 0]))>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_declare_and_use_var.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_declare_and_use_var.snap index ebab169fb..93af2abac 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_declare_and_use_var.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_declare_and_use_var.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 124 expression: "pub fn go(x) {\n let assert <> = x\n name\n}" --- -module(my@mod). @@ -7,13 +8,14 @@ expression: "pub fn go(x) {\n let assert < bitstring(). go(X) -> <> = case X of <<_:8, _:Name_size/binary>> -> X; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"go"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_discard.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_discard.snap index 8b2e7ca7e..c57ab35c6 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_discard.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_discard.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 96 expression: "\npub fn bit_array_discard(x) -> Bool {\n case x {\n <<_:utf8, rest:bytes>> -> True\n _ -> False\n }\n}\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn bit_array_discard(x) -> Bool {\n case x {\n <<_:utf8, res -export([bit_array_discard/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec bit_array_discard(bitstring()) -> boolean(). bit_array_discard(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_discard1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_discard1.snap index 3b33d99ba..33abbcecb 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_discard1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_discard1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 110 expression: "\npub fn bit_array_discard(x) -> Bool {\n case x {\n <<_discardme:utf8, rest:bytes>> -> True\n _ -> False\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn bit_array_discard(x) -> Bool {\n case x {\n <<_discardme: -export([bit_array_discard/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec bit_array_discard(bitstring()) -> boolean(). bit_array_discard(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_float.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_float.snap index 16dc4f7cc..f8d33565e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_float.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_float.snap @@ -1,12 +1,14 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs -expression: "pub fn main() {\n let b = 16\n let floats = <<1.0:16-float, 5.0:float-32, 6.0:float-64-little, 1.0:float-size(b)>>\n let assert <<1.0:16-float, 5.0:float-32, 6.0:float-64-little, 1.0:float-size(b)>> = floats \n}" +assertion_line: 21 +expression: "pub fn main() {\n let b = 16\n let floats = <<1.0:16-float, 5.0:float-32, 6.0:float-64-little, 1.0:float-size(b)>>\n let assert <<1.0:16-float, 5.0:float-32, 6.0:float-64-little, 1.0:float-size(b)>> = floats\n}" --- -module(my@mod). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([main/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec main() -> bitstring(). main() -> B = 16, @@ -18,7 +20,7 @@ main() -> <<1.0:16/float, 5.0:32/float, 6.0:64/float-little, 1.0:B/float>> -> Floats; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap new file mode 100644 index 000000000..38773cd6d --- /dev/null +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap @@ -0,0 +1,14 @@ +--- +source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 167 +expression: "\nconst a = <<\"hello\", \" \", \"world\">>\npub fn main() { a }\n" +--- +-module(my@mod). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). + +-export([main/0]). + +-file("/root/project/test/my/mod.gleam", 3). +-spec main() -> bitstring(). +main() -> + <<"hello"/utf8, " "/utf8, "world"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap new file mode 100644 index 000000000..45ec11c1c --- /dev/null +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap @@ -0,0 +1,14 @@ +--- +source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 177 +expression: "\npub fn main() {\n <<\"hello\", \" \", \"world\">>\n}" +--- +-module(my@mod). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). + +-export([main/0]). + +-file("/root/project/test/my/mod.gleam", 2). +-spec main() -> bitstring(). +main() -> + <<"hello"/utf8, " "/utf8, "world"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_pattern_is_treated_as_utf8.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_pattern_is_treated_as_utf8.snap new file mode 100644 index 000000000..7d1808405 --- /dev/null +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__bit_array_literal_string_pattern_is_treated_as_utf8.snap @@ -0,0 +1,20 @@ +--- +source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 187 +expression: "\npub fn main() {\n case <<>> {\n <<\"a\", \"b\", _:bits>> -> 1\n _ -> 2\n }\n}" +--- +-module(my@mod). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). + +-export([main/0]). + +-file("/root/project/test/my/mod.gleam", 2). +-spec main() -> integer(). +main() -> + case <<>> of + <<"a"/utf8, "b"/utf8, _/bitstring>> -> + 1; + + _ -> + 2 + end. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__discard_utf8_pattern.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__discard_utf8_pattern.snap new file mode 100644 index 000000000..a483cbeba --- /dev/null +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__discard_utf8_pattern.snap @@ -0,0 +1,24 @@ +--- +source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 200 +expression: "\npub fn main() {\n let assert <<_:utf8, rest:bits>> = <<>>\n}" +--- +-module(my@mod). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). + +-export([main/0]). + +-file("/root/project/test/my/mod.gleam", 2). +-spec main() -> bitstring(). +main() -> + _assert_subject = <<>>, + <<_/utf8, Rest/bitstring>> = case _assert_subject of + <<_/utf8, _/bitstring>> -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => let_assert, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, + value => _assert_fail, + module => <<"my/mod"/utf8>>, + function => <<"main"/utf8>>, + line => 3}) + end. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__negative_size.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__negative_size.snap index c5afccb3a..168b7adaf 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__negative_size.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__negative_size.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 134 expression: "\npub fn main() {\n <<1:size(-1)>>\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n <<1:size(-1)>>\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> bitstring(). main() -> <<1:0>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__unicode_bit_array_1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__unicode_bit_array_1.snap index d458a0e00..dafd28a7b 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__unicode_bit_array_1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__unicode_bit_array_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 146 expression: "\n pub fn main() {\n let emoji = \"\\u{1F600}\"\n let arr = <>\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n pub fn main() {\n let emoji = \"\\u{1F600}\"\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> bitstring(). main() -> Emoji = <<"\x{1F600}"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__unicode_bit_array_2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__unicode_bit_array_2.snap index a8cdd0799..5bf5ce434 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__unicode_bit_array_2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__bit_arrays__unicode_bit_array_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/bit_arrays.rs +assertion_line: 157 expression: "\n pub fn main() {\n let arr = <<\"\\u{1F600}\":utf8>>\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n pub fn main() {\n let arr = <<\"\\u{1F600}\":utf8>>\n} -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> bitstring(). main() -> Arr = <<"\x{1F600}"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__alternative_pattern_variable_rewriting.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__alternative_pattern_variable_rewriting.snap index f1eacba9e..82dd9aaf8 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__alternative_pattern_variable_rewriting.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__alternative_pattern_variable_rewriting.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/case.rs +assertion_line: 6 expression: "\npub fn myfun(mt) {\n case mt {\n 1 | _ ->\n 1\n |> Ok\n }\n 1\n |> Ok\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn myfun(mt) {\n case mt {\n 1 | _ ->\n 1\n |> -export([myfun/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec myfun(integer()) -> {ok, integer()} | {error, any()}. myfun(Mt) -> case Mt of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__negative_zero_pattern.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__negative_zero_pattern.snap index 0c677d80c..4aa4f4036 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__negative_zero_pattern.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__negative_zero_pattern.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/case.rs +assertion_line: 39 expression: "\npub fn main(x) {\n case x {\n -0.0 -> 1\n _ -> 2\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(x) {\n case x {\n -0.0 -> 1\n _ -> 2\n }\n}\n -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(float()) -> integer(). main(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__not.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__not.snap index bac1aa7fb..5490a64a5 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__not.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__not.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/case.rs +assertion_line: 53 expression: "pub fn main(x, y) {\n case x {\n _ if !y -> 0\n _ -> 1\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn main(x, y) {\n case x {\n _ if !y -> 0\n _ -> 1\n }\ -export([main/2]). +-file("/root/project/test/my/mod.gleam", 1). -spec main(any(), boolean()) -> integer(). main(X, Y) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__not_two.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__not_two.snap index 72fe75175..da4ab3db0 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__not_two.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__not_two.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/case.rs +assertion_line: 66 expression: "pub fn main(x, y) {\n case x {\n _ if !y && !x -> 0\n _ -> 1\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn main(x, y) {\n case x {\n _ if !y && !x -> 0\n _ -> 1 -export([main/2]). +-file("/root/project/test/my/mod.gleam", 1). -spec main(boolean(), boolean()) -> integer(). main(X, Y) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__positive_zero_pattern.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__positive_zero_pattern.snap index c306179b6..6715911ee 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__positive_zero_pattern.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__positive_zero_pattern.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/case.rs +assertion_line: 24 expression: "\npub fn main(x) {\n case x {\n 0.0 -> 1\n _ -> 2\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(x) {\n case x {\n 0.0 -> 1\n _ -> 2\n }\n}\n" -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(float()) -> integer(). main(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__spread_empty_list.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__spread_empty_list.snap index c7e4cf69d..77de748da 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__spread_empty_list.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__spread_empty_list.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/case.rs +assertion_line: 80 expression: "\npub fn main() {\n case [] {\n [..] -> 1\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case [] {\n [..] -> 1\n }\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case [] of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__spread_empty_list_assigning.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__spread_empty_list_assigning.snap index 26953cd17..2831d4b40 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__spread_empty_list_assigning.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__case__spread_empty_list_assigning.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/case.rs +assertion_line: 94 expression: "\npub fn main() {\n case [] {\n [..rest] -> rest\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case [] {\n [..rest] -> rest\n }\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> list(any()). main() -> case [] of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__conditional_compilation__included_attribute_syntax.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__conditional_compilation__included_attribute_syntax.snap index fa213000a..7c32c3bbb 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__conditional_compilation__included_attribute_syntax.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__conditional_compilation__included_attribute_syntax.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/conditional_compilation.rs +assertion_line: 14 expression: "@target(erlang)\n pub fn main() { 1 }\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "@target(erlang)\n pub fn main() { 1 }\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> 1. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__const_generalise.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__const_generalise.snap index 7212335aa..cec62a33e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__const_generalise.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__const_generalise.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 53 expression: "\nfn identity(a: a) -> a {\na\n}\n\nconst id = identity\n\npub fn main(){\n let num = id(1)\n let word = id(\"Word\")\n}" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\nfn identity(a: a) -> a {\na\n}\n\nconst id = identity\n\npub fn -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec identity(I) -> I. identity(A) -> A. +-file("/root/project/test/my/mod.gleam", 8). -spec main() -> binary(). main() -> Num = identity(1), diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_private_function.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_private_function.snap index d74a587aa..1381f7053 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_private_function.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_private_function.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 70 expression: "\n fn identity(a) {\n a\n }\n\n pub const id = identity\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n fn identity(a) {\n a\n }\n\n -export([identity/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec identity(I) -> I. identity(A) -> A. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_record_with_nested_private_function_field.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_record_with_nested_private_function_field.snap index a2b2bdab0..e69833d7b 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_record_with_nested_private_function_field.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_record_with_nested_private_function_field.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 100 expression: "\n fn identity(a) {\n a\n }\n\n pub type Mapper(b) {\n Mapper(fn(b) -> b)\n }\n\n pub type Funcs(b) {\n Funcs(mapper: Mapper(b))\n }\n\n pub const id_mapper = Funcs(Mapper(identity))\n " --- -module(my@mod). @@ -12,6 +13,7 @@ expression: "\n fn identity(a) {\n a\n }\n\n -type funcs(J) :: {funcs, mapper(J)}. +-file("/root/project/test/my/mod.gleam", 2). -spec identity(K) -> K. identity(A) -> A. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_record_with_private_function_field.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_record_with_private_function_field.snap index 3776fff85..f8bbba83b 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_record_with_private_function_field.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__pub_const_equal_to_record_with_private_function_field.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 83 expression: "\n fn identity(a) {\n a\n }\n\n pub type Mapper(b) {\n Mapper(fn(b) -> b)\n }\n\n pub const id_mapper = Mapper(identity)\n " --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\n fn identity(a) {\n a\n }\n\n -type mapper(I) :: {mapper, fun((I) -> I)}. +-file("/root/project/test/my/mod.gleam", 2). -spec identity(J) -> J. identity(A) -> A. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__record_constructor.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__record_constructor.snap index 1800b2e14..ebd562928 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__record_constructor.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__record_constructor.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 6 expression: "\npub type X {\n X(Int)\n}\n\npub const z = X\n\npub fn main() {\n z\n}" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\npub type X {\n X(Int)\n}\n\npub const z = X\n\npub fn main() {\n -type x() :: {x, integer()}. +-file("/root/project/test/my/mod.gleam", 8). -spec main() -> fun((integer()) -> x()). main() -> fun(Field@0) -> {x, Field@0} end. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__record_constructor_in_tuple.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__record_constructor_in_tuple.snap index f17340a6b..c4931f7c8 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__record_constructor_in_tuple.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__record_constructor_in_tuple.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 23 expression: "\npub type X {\n X(Int)\n}\n\npub const z = #(X)\n\npub fn main() {\n z\n}" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\npub type X {\n X(Int)\n}\n\npub const z = #(X)\n\npub fn main() -type x() :: {x, integer()}. +-file("/root/project/test/my/mod.gleam", 8). -spec main() -> {fun((integer()) -> x())}. main() -> {fun(Field@0) -> {x, Field@0} end}. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_internal.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_internal.snap index 2f49e7d48..86c591719 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_internal.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_internal.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 168 expression: "\n fn identity(a) {\n a\n }\n\n pub type Mapper(b) {\n Mapper(fn(b) -> b)\n }\n\n @internal\n pub const id_mapper = Mapper(identity)\n " --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\n fn identity(a) {\n a\n -type mapper(I) :: {mapper, fun((I) -> I)}. +-file("/root/project/test/my/mod.gleam", 2). -spec identity(J) -> J. identity(A) -> A. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_list.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_list.snap index 3d14a9e16..2c3a9812b 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_list.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_list.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 186 expression: "\n fn identity(a) {\n a\n }\n\n pub const funcs = [identity]\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n fn identity(a) {\n a\n }\n\n -export([identity/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec identity(I) -> I. identity(A) -> A. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_tuple.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_tuple.snap index 46f7efd08..0baace7ac 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_tuple.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_private_in_tuple.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 199 expression: "\n fn identity(a) {\n a\n }\n\n pub const funcs = #(identity)\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n fn identity(a) {\n a\n }\n\n -export([identity/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec identity(I) -> I. identity(A) -> A. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_qualified_pub_const_equal_to_record_with_private_function_field.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_qualified_pub_const_equal_to_record_with_private_function_field.snap index 7ec0781b3..6c323db2f 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_qualified_pub_const_equal_to_record_with_private_function_field.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_qualified_pub_const_equal_to_record_with_private_function_field.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 151 expression: "\n fn identity(a) {\n a\n }\n\n pub type Mapper(b) {\n Mapper(fn(b) -> b)\n }\n\n pub const id_mapper = Mapper(identity)\n " --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\n fn identity(a) {\n a\n -type mapper(I) :: {mapper, fun((I) -> I)}. +-file("/root/project/test/my/mod.gleam", 2). -spec identity(J) -> J. identity(A) -> A. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_unqualified_pub_const_equal_to_private_function.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_unqualified_pub_const_equal_to_private_function.snap index c98bfb208..6062f45d4 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_unqualified_pub_const_equal_to_private_function.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_unqualified_pub_const_equal_to_private_function.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 121 expression: "\n fn identity(a) {\n a\n }\n\n pub const id = identity\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n fn identity(a) {\n a\n -export([identity/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec identity(I) -> I. identity(A) -> A. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_unqualified_pub_const_equal_to_record_with_private_function_field.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_unqualified_pub_const_equal_to_record_with_private_function_field.snap index 7ec0781b3..fe0159355 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_unqualified_pub_const_equal_to_record_with_private_function_field.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__consts__use_unqualified_pub_const_equal_to_record_with_private_function_field.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/consts.rs +assertion_line: 134 expression: "\n fn identity(a) {\n a\n }\n\n pub type Mapper(b) {\n Mapper(fn(b) -> b)\n }\n\n pub const id_mapper = Mapper(identity)\n " --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\n fn identity(a) {\n a\n -type mapper(I) :: {mapper, fun((I) -> I)}. +-file("/root/project/test/my/mod.gleam", 2). -spec identity(J) -> J. identity(A) -> A. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__attribute_erlang.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__attribute_erlang.snap index 16b20d26b..291d8c48b 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__attribute_erlang.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__attribute_erlang.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 105 expression: "\n@external(erlang, \"one\", \"one\")\npub fn one(x: Int) -> Int {\n todo\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n@external(erlang, \"one\", \"one\")\npub fn one(x: Int) -> Int {\ -export([one/1]). +-file("/root/project/test/my/mod.gleam", 3). -spec one(integer()) -> integer(). one(X) -> one:one(X). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__attribute_javascript.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__attribute_javascript.snap index 0252755f9..d078542c1 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__attribute_javascript.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__attribute_javascript.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 117 expression: "\n@external(javascript, \"./one.mjs\", \"one\")\npub fn one(x: Int) -> Int {\n todo\n}\n" --- -module(my@mod). @@ -7,10 +8,11 @@ expression: "\n@external(javascript, \"./one.mjs\", \"one\")\npub fn one(x: Int) -export([one/1]). +-file("/root/project/test/my/mod.gleam", 3). -spec one(integer()) -> integer(). one(X) -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"one"/utf8>>, line => 4}). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__both_externals_no_valid_impl.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__both_externals_no_valid_impl.snap index 527fbc5b4..f48ac4331 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__both_externals_no_valid_impl.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__both_externals_no_valid_impl.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 304 expression: "\n@external(javascript, \"one\", \"one\")\npub fn js() -> Nil\n\n@external(erlang, \"one\", \"one\")\npub fn erl() -> Nil\n\npub fn should_not_be_generated() {\n js()\n erl()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n@external(javascript, \"one\", \"one\")\npub fn js() -> Nil\n\n@e -export([erl/0]). +-file("/root/project/test/my/mod.gleam", 6). -spec erl() -> nil. erl() -> one:one(). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__elixir.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__elixir.snap index 9294abc38..5d3325ac6 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__elixir.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__elixir.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 247 expression: "\npub fn main() {\n #(do, do())\n}\n\n@external(erlang, \"Elixir.String\", \"main\")\nfn do() -> Int\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n #(do, do())\n}\n\n@external(erlang, \"Elixir.S -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> {fun(() -> integer()), integer()}. main() -> {fun 'Elixir.String':main/0, 'Elixir.String':main()}. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__erlang_and_javascript.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__erlang_and_javascript.snap index 936e13378..476beb4c4 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__erlang_and_javascript.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__erlang_and_javascript.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 129 expression: "\n@external(erlang, \"one\", \"one\")\n@external(javascript, \"./one.mjs\", \"one\")\npub fn one(x: Int) -> Int {\n todo\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n@external(erlang, \"one\", \"one\")\n@external(javascript, \"./on -export([one/1]). +-file("/root/project/test/my/mod.gleam", 4). -spec one(integer()) -> integer(). one(X) -> one:one(X). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__inlining_external_functions_from_another_module.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__inlining_external_functions_from_another_module.snap index bfe7bfdf4..43f381d59 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__inlining_external_functions_from_another_module.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__inlining_external_functions_from_another_module.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 63 expression: "import atom\npub fn main() {\n atom.make(\"ok\")\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "import atom\npub fn main() {\n atom.make(\"ok\")\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> binary(). main() -> erlang:binary_to_atom(<<"ok"/utf8>>). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__integration_test1_3.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__integration_test1_3.snap index df086bcf6..772ae503e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__integration_test1_3.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__integration_test1_3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 5 expression: "\n@external(erlang, \"Elixir.MyApp\", \"run\")\npub fn run() -> Int\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n@external(erlang, \"Elixir.MyApp\", \"run\")\npub fn run() -> Int -export([run/0]). +-file("/root/project/test/my/mod.gleam", 3). -spec run() -> integer(). run() -> 'Elixir.MyApp':run(). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__integration_test7.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__integration_test7.snap index 580414a8c..dba3d5916 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__integration_test7.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__integration_test7.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 15 expression: "\n@external(erlang, \"try\", \"and\")\npub fn receive() -> Int\npub fn catch(x) { receive() }\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\n@external(erlang, \"try\", \"and\")\npub fn receive() -> Int\npub -export(['receive'/0, 'catch'/1]). +-file("/root/project/test/my/mod.gleam", 3). -spec 'receive'() -> integer(). 'receive'() -> 'try':'and'(). +-file("/root/project/test/my/mod.gleam", 4). -spec 'catch'(any()) -> integer(). 'catch'(X) -> 'try':'and'(). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__javascript_only.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__javascript_only.snap index 99cd80c5e..1bd4426da 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__javascript_only.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__javascript_only.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 271 expression: "\npub fn should_be_generated(x: Int) -> Int {\n x\n}\n\n@external(javascript, \"one\", \"one\")\npub fn should_not_be_generated(x: Int) -> Int\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn should_be_generated(x: Int) -> Int {\n x\n}\n\n@external( -export([should_be_generated/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec should_be_generated(integer()) -> integer(). should_be_generated(X) -> X. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__javascript_only_indirect.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__javascript_only_indirect.snap index 44e4f09e2..84166b6e6 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__javascript_only_indirect.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__javascript_only_indirect.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 285 expression: "\npub fn should_be_generated(x: Int) -> Int {\n x\n}\n\n@external(javascript, \"one\", \"one\")\npub fn should_not_be_generated(x: Int) -> Int\n\npub fn also_should_not_be_generated() {\n should_not_be_generated(1)\n |> should_be_generated\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn should_be_generated(x: Int) -> Int {\n x\n}\n\n@external( -export([should_be_generated/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec should_be_generated(integer()) -> integer(). should_be_generated(X) -> X. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__no_body.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__no_body.snap index 4651c0254..0430155c4 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__no_body.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__no_body.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 214 expression: "\n@external(erlang, \"one\", \"one\")\npub fn one(x: Int) -> Int\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n@external(erlang, \"one\", \"one\")\npub fn one(x: Int) -> Int\n" -export([one/1]). +-file("/root/project/test/my/mod.gleam", 3). -spec one(integer()) -> integer(). one(X) -> one:one(X). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private.snap index 1ee735085..4e8c5e6a0 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 233 expression: "\npub fn main() {\n do()\n}\n\n@external(erlang, \"library\", \"main\")\nfn do() -> Int\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n do()\n}\n\n@external(erlang, \"library\", \"ma -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> library:main(). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private_external_function_calls.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private_external_function_calls.snap index ae199e041..81705cf77 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private_external_function_calls.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private_external_function_calls.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 27 expression: "\n@external(erlang, \"m\", \"f\")\nfn go(x x: Int, y y: Int) -> Int\n\npub fn x() { go(x: 1, y: 2) go(y: 3, x: 4) }" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n@external(erlang, \"m\", \"f\")\nfn go(x x: Int, y y: Int) -> Int -export([x/0]). +-file("/root/project/test/my/mod.gleam", 5). -spec x() -> integer(). x() -> m:f(1, 2), diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private_local_function_references.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private_local_function_references.snap index 25028767f..fd10afec1 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private_local_function_references.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__private_local_function_references.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 52 expression: "\n@external(erlang, \"m\", \"f\")\nfn go(x: Int, y: Int) -> Int\npub fn x() { go }\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n@external(erlang, \"m\", \"f\")\nfn go(x: Int, y: Int) -> Int\npu -export([x/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec x() -> fun((integer(), integer()) -> integer()). x() -> fun m:f/2. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__public_elixir.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__public_elixir.snap index 5f932a30a..1435a80e3 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__public_elixir.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__public_elixir.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 261 expression: "\n@external(erlang, \"Elixir.String\", \"main\")\npub fn do() -> Int\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n@external(erlang, \"Elixir.String\", \"main\")\npub fn do() -> In -export([do/0]). +-file("/root/project/test/my/mod.gleam", 3). -spec do() -> integer(). do() -> 'Elixir.String':main(). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__public_local_function_calls.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__public_local_function_calls.snap index c8adeb0db..475c441e7 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__public_local_function_calls.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__public_local_function_calls.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 40 expression: "\n@external(erlang, \"m\", \"f\")\npub fn go(x x: Int, y y: Int) -> Int\nfn x() { go(x: 1, y: 2) go(y: 3, x: 4) }\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\n@external(erlang, \"m\", \"f\")\npub fn go(x x: Int, y y: Int) -> -export([go/2]). +-file("/root/project/test/my/mod.gleam", 3). -spec go(integer(), integer()) -> integer(). go(X, Y) -> m:f(X, Y). +-file("/root/project/test/my/mod.gleam", 4). -spec x() -> integer(). x() -> m:f(1, 2), diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__unqualified_inlining_external_functions_from_another_module.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__unqualified_inlining_external_functions_from_another_module.snap index 3647d0af9..8806c145b 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__unqualified_inlining_external_functions_from_another_module.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__external_fn__unqualified_inlining_external_functions_from_another_module.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/external_fn.rs +assertion_line: 84 expression: "import atom.{make}\npub fn main() {\n make(\"ok\")\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "import atom.{make}\npub fn main() {\n make(\"ok\")\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> binary(). main() -> erlang:binary_to_atom(<<"ok"/utf8>>). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__function_as_value.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__function_as_value.snap index fea31f288..a3b1ff852 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__function_as_value.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__function_as_value.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/functions.rs +assertion_line: 5 expression: "\nfn other() {\n Nil\n}\n\npub fn main() {\n other\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\nfn other() {\n Nil\n}\n\npub fn main() {\n other\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec other() -> nil. other() -> nil. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> fun(() -> nil). main() -> fun other/0. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__function_called.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__function_called.snap index 175a55f5c..2e620c3e3 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__function_called.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__function_called.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/functions.rs +assertion_line: 62 expression: "\npub fn main() {\n main()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n main()\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> any(). main() -> main(). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_aliased_imported_function_as_value.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_aliased_imported_function_as_value.snap index 0adb6bd5c..702931b69 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_aliased_imported_function_as_value.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_aliased_imported_function_as_value.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/functions.rs +assertion_line: 48 expression: "\nimport some/other.{wibble as wobble}\n\npub fn main() {\n wobble\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some/other.{wibble as wobble}\n\npub fn main() {\n wobble -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> fun(() -> nil). main() -> fun some@other:wibble/0. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_aliased_imported_function_called.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_aliased_imported_function_called.snap index 20144a2d5..fcd3a945c 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_aliased_imported_function_called.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_aliased_imported_function_called.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/functions.rs +assertion_line: 101 expression: "\nimport some/other.{wibble as wobble}\n\npub fn main() {\n wobble()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some/other.{wibble as wobble}\n\npub fn main() {\n wobble -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> nil. main() -> some@other:wibble(). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_imported_function_as_value.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_imported_function_as_value.snap index 1695af45b..f090ea19a 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_imported_function_as_value.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_imported_function_as_value.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/functions.rs +assertion_line: 20 expression: "\nimport some/other\n\npub fn main() {\n other.wibble\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some/other\n\npub fn main() {\n other.wibble\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> fun(() -> nil). main() -> fun some@other:wibble/0. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_imported_function_called.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_imported_function_called.snap index 8274879b9..9d1139dab 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_imported_function_called.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_imported_function_called.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/functions.rs +assertion_line: 73 expression: "\nimport some/other\n\npub fn main() {\n other.wibble()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some/other\n\npub fn main() {\n other.wibble()\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> nil. main() -> some@other:wibble(). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_unqualified_imported_function_as_value.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_unqualified_imported_function_as_value.snap index 40f8937d4..3a8f59e0f 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_unqualified_imported_function_as_value.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_unqualified_imported_function_as_value.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/functions.rs +assertion_line: 34 expression: "\nimport some/other.{wibble}\n\npub fn main() {\n wibble\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some/other.{wibble}\n\npub fn main() {\n wibble\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> fun(() -> nil). main() -> fun some@other:wibble/0. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_unqualified_imported_function_called.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_unqualified_imported_function_called.snap index c28bc7758..841ff3513 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_unqualified_imported_function_called.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__functions__nested_unqualified_imported_function_called.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/functions.rs +assertion_line: 87 expression: "\nimport some/other.{wibble}\n\npub fn main() {\n wibble()\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nimport some/other.{wibble}\n\npub fn main() {\n wibble()\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> nil. main() -> some@other:wibble(). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards.snap index 83ed20738..2d57041be 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 6 expression: "\npub fn main(args) {\n case args {\n x if x == args -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(args) {\n case args {\n x if x == args -> 1\n -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(any()) -> integer(). main(Args) -> case Args of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards20.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards20.snap index 1bce0e1c9..3e2a85c40 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards20.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards20.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 162 expression: "\npub fn main() {\n let x = 0.123\n case x {\n _ if 0.123 <. x -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let x = 0.123\n case x {\n _ if 0.123 <. x -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> X = 0.123, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards21.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards21.snap index c57197e9c..1dc62e012 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards21.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards21.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 177 expression: "\npub fn main(x) {\n case x {\n _ if x == [1, 2, 3] -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(x) {\n case x {\n _ if x == [1, 2, 3] -> 1\n _ -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(list(integer())) -> integer(). main(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards22.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards22.snap index aec4478e9..f2a93ead6 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards22.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards22.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 191 expression: "\npub fn main() {\n let x = 0\n case x {\n 0 -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let x = 0\n case x {\n 0 -> 1\n _ -> 0\ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> X = 0, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards23.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards23.snap index f5f2e3f85..be153236a 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards23.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards23.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 208 expression: "\npub fn main() {\n let x = #(1, 2, 3)\n case x {\n _ if x == #(1, 2, 3) -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let x = #(1, 2, 3)\n case x {\n _ if x == -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> X = {1, 2, 3}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards24.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards24.snap index 463a7ef2d..6b7017325 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards24.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards24.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 223 expression: "\npub fn main() {\n let x = #(1, 2, 3)\n case x {\n _ if x == #(1, 2, 3) -> 1\n _ if x == #(2, 3, 4) -> 2\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let x = #(1, 2, 3)\n case x {\n _ if x == -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> X = {1, 2, 3}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards25.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards25.snap index 65a8493a5..a9fe1985d 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards25.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards25.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 241 expression: "\npub fn main() {\n let x = 0\n case x {\n _ if x == 0 -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let x = 0\n case x {\n _ if x == 0 -> 1\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> X = 0, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards26.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards26.snap index bec2e4151..36f7858af 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards26.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards26.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 256 expression: "\npub fn main() {\n let x = 0\n case x {\n _ if 0 < x -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let x = 0\n case x {\n _ if 0 < x -> 1\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> X = 0, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards27.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards27.snap index 5f7a668d3..a5749945c 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards27.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards27.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 273 expression: "\npub fn main() {\n case \"test\" {\n x if x == \"test\" -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case \"test\" {\n x if x == \"test\" -> 1\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case <<"test"/utf8>> of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards28.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards28.snap index ce42750a7..dd9af7843 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards28.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards28.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 289 expression: "\n type Test { Test(x: Int, y: Float) }\n pub fn main() {\n let x = Test(1, 3.0)\n case x {\n _ if x == Test(1, 1.0) -> 1\n _ if x == Test(y: 2.0, x: 2) -> 2\n _ if x != Test(2, 3.0) -> 2\n _ -> 0\n }\n }\n" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\n type Test { Test(x: Int, y: Float) }\n pub fn main() {\n -type test() :: {test, integer(), float()}. +-file("/root/project/test/my/mod.gleam", 3). -spec main() -> integer(). main() -> X = {test, 1, 3.0}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards29.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards29.snap index db081721f..e60a43cdb 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards29.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards29.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 309 expression: "\npub fn main() {\n case 0.1, 1.0 {\n x, y if x <. y -> 1\n _, _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case 0.1, 1.0 {\n x, y if x <. y -> 1\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case {0.1, 1.0} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards30.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards30.snap index 2bfc18d36..598b2c00e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards30.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards30.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 323 expression: "\npub fn main() {\n case 0.1, 1.0 {\n x, y if x <=. y -> 1\n _, _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case 0.1, 1.0 {\n x, y if x <=. y -> 1\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case {0.1, 1.0} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards31.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards31.snap index 2ff7f79a4..48af3c20d 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards31.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards31.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 337 expression: "\npub fn main(args) {\n case args {\n [x] | [x, _] if x -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(args) {\n case args {\n [x] | [x, _] if x -> 1\n -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(list(boolean())) -> integer(). main(Args) -> case Args of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_1.snap index c6e7bf278..0e87a5901 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 20 expression: "\npub fn main(args) {\n case args {\n x if {x != x} == {args == args} -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(args) {\n case args {\n x if {x != x} == {args == -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(any()) -> integer(). main(Args) -> case Args of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_10.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_10.snap index 8829dcb03..73e37385f 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_10.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_10.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 147 expression: "\npub fn main() {\n let x = 0.123\n case x {\n _ if x == 3.14 -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let x = 0.123\n case x {\n _ if x == 3.14 -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> X = 0.123, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_2.snap index 8e2d1bb18..b64727798 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 34 expression: "\npub fn main(args) {\n case args {\n x if x && x || x == x && x -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(args) {\n case args {\n x if x && x || x == x && -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(boolean()) -> integer(). main(Args) -> case Args of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_3.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_3.snap index 604c36088..b709378e6 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_3.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 48 expression: "\npub fn main() {\n case 1, 0 {\n x, y if x > y -> 1\n _, _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case 1, 0 {\n x, y if x > y -> 1\n _, _ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case {1, 0} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_4.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_4.snap index cf90ab4ce..252cb34b9 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_4.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_4.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 62 expression: "\npub fn main() {\n case 1, 0 {\n x, y if x >= y -> 1\n _, _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case 1, 0 {\n x, y if x >= y -> 1\n _, _ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case {1, 0} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_5.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_5.snap index 77aedf1bb..a938075dc 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_5.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_5.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 76 expression: "\npub fn main() {\n case 1, 0 {\n x, y if x < y -> 1\n _, _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case 1, 0 {\n x, y if x < y -> 1\n _, _ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case {1, 0} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_6.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_6.snap index 73c09cf9e..59cb9307e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_6.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_6.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 90 expression: "\npub fn main() {\n case 1, 0 {\n x, y if x <= y -> 1\n _, _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case 1, 0 {\n x, y if x <= y -> 1\n _, _ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case {1, 0} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_7.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_7.snap index 550599673..90c433edc 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_7.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_7.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 104 expression: "\npub fn main() {\n case 1.0, 0.1 {\n x, y if x >. y -> 1\n _, _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case 1.0, 0.1 {\n x, y if x >. y -> 1\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case {1.0, 0.1} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_8.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_8.snap index 2038ccf6d..e49c52882 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_8.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_8.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 118 expression: "\npub fn main() {\n case 1.0, 0.1 {\n x, y if x >=. y -> 1\n _, _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case 1.0, 0.1 {\n x, y if x >=. y -> 1\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case {1.0, 0.1} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_9.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_9.snap index c5e311490..f38605dcf 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_9.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__clause_guards_9.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 132 expression: "\npub fn main() {\n let x = 0.123\n case x {\n 99.9854 -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let x = 0.123\n case x {\n 99.9854 -> 1\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> X = 0.123, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__constants_in_guards.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__constants_in_guards.snap index 3291d4c2d..0160d86a7 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__constants_in_guards.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__constants_in_guards.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 351 expression: "\npub const string_value = \"constant value\"\npub const float_value = 3.14\npub const int_value = 42\npub const tuple_value = #(1, 2.0, \"3\")\npub const list_value = [1, 2, 3]\n\npub fn main(arg) {\n let _ = list_value\n case arg {\n #(w, x, y, z) if w == tuple_value && x == string_value && y >. float_value && z == int_value -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub const string_value = \"constant value\"\npub const float_valu -export([main/1]). +-file("/root/project/test/my/mod.gleam", 8). -spec main({{integer(), float(), binary()}, binary(), float(), integer()}) -> integer(). main(Arg) -> _ = [1, 2, 3], diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__constants_in_guards1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__constants_in_guards1.snap index 8dd59b361..97a21b4b4 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__constants_in_guards1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__constants_in_guards1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 372 expression: "\npub const list = [1, 2, 3]\n\npub fn main(arg) {\n case arg {\n _ if arg == list -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub const list = [1, 2, 3]\n\npub fn main(arg) {\n case arg {\n -export([main/1]). +-file("/root/project/test/my/mod.gleam", 4). -spec main(list(integer())) -> integer(). main(Arg) -> case Arg of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__field_access.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__field_access.snap index bff822628..d02ff9417 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__field_access.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__field_access.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 452 expression: "\n pub type Person {\n Person(username: String, name: String, age: Int)\n }\n \n pub fn main() {\n let given_name = \"jack\"\n let raiden = Person(\"raiden\", \"jack\", 31)\n \n case given_name {\n name if name == raiden.name -> \"It's jack\"\n _ -> \"It's not jack\"\n }\n }\n " --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\n pub type Person {\n Person(username: String, nam -type person() :: {person, binary(), binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> binary(). main() -> Given_name = <<"jack"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_access.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_access.snap index 72b06c006..e85ab40e0 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_access.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_access.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 568 expression: "\n import hero\n pub fn main() {\n let name = \"Tony Stark\"\n case name {\n n if n == hero.ironman.name -> True\n _ -> False\n }\n }\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n import hero\n pub fn main() {\n let -export([main/0]). +-file("/root/project/test/my/mod.gleam", 3). -spec main() -> boolean(). main() -> Name = <<"Tony Stark"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_list_access.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_list_access.snap index d834047c5..d4c47e17d 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_list_access.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_list_access.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 522 expression: "\n import hero\n pub fn main() {\n let names = [\"Tony Stark\", \"Bruce Wayne\"]\n case names {\n n if n == hero.heroes -> True\n _ -> False\n }\n }\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n import hero\n pub fn main() {\n let -export([main/0]). +-file("/root/project/test/my/mod.gleam", 3). -spec main() -> boolean(). main() -> Names = [<<"Tony Stark"/utf8>>, <<"Bruce Wayne"/utf8>>], diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_nested_access.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_nested_access.snap index 18667beab..50daa73ca 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_nested_access.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_nested_access.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 594 expression: "\n import hero\n pub fn main() {\n let name = \"Bruce Wayne\"\n case name {\n n if n == hero.batman.secret_identity.name -> True\n _ -> False\n }\n }\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n import hero\n pub fn main() {\n let -export([main/0]). +-file("/root/project/test/my/mod.gleam", 3). -spec main() -> boolean(). main() -> Name = <<"Bruce Wayne"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_string_access.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_string_access.snap index 77606da49..1fa3e392a 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_string_access.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_string_access.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 499 expression: "\n import hero\n pub fn main() {\n let name = \"Tony Stark\"\n case name {\n n if n == hero.ironman -> True\n _ -> False\n }\n }\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n import hero\n pub fn main() {\n let -export([main/0]). +-file("/root/project/test/my/mod.gleam", 3). -spec main() -> boolean(). main() -> Name = <<"Tony Stark"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_tuple_access.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_tuple_access.snap index 5b6d6c952..57497a73c 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_tuple_access.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__module_tuple_access.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 545 expression: "\n import hero\n pub fn main() {\n let name = \"Tony Stark\"\n case name {\n n if n == hero.hero.1 -> True\n _ -> False\n }\n }\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n import hero\n pub fn main() {\n let -export([main/0]). +-file("/root/project/test/my/mod.gleam", 3). -spec main() -> boolean(). main() -> Name = <<"Tony Stark"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__nested_record_access.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__nested_record_access.snap index 0d9204222..67df02132 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__nested_record_access.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__nested_record_access.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 473 expression: "\npub type A {\n A(b: B)\n}\n\npub type B {\n B(c: C)\n}\n\npub type C {\n C(d: Bool)\n}\n\npub fn a(a: A) {\n case a {\n _ if a.b.c.d -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -14,6 +15,7 @@ expression: "\npub type A {\n A(b: B)\n}\n\npub type B {\n B(c: C)\n}\n\npub t -type c() :: {c, boolean()}. +-file("/root/project/test/my/mod.gleam", 14). -spec a(a()) -> integer(). a(A) -> case A of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards.snap index 47b61ac00..5d6222eae 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 388 expression: "\npub const string_value = \"constant value\"\n\npub fn main(arg) {\n case arg {\n _ if arg == string_value -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub const string_value = \"constant value\"\n\npub fn main(arg) { -export([main/1]). +-file("/root/project/test/my/mod.gleam", 4). -spec main(binary()) -> integer(). main(Arg) -> case Arg of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards1.snap index fc8aa6438..5328e2bd2 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 404 expression: "\npub const bits = <<1, \"ok\":utf8, 3, 4:50>>\n\npub fn main(arg) {\n case arg {\n _ if arg == bits -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub const bits = <<1, \"ok\":utf8, 3, 4:50>>\n\npub fn main(arg) -export([main/1]). +-file("/root/project/test/my/mod.gleam", 4). -spec main(bitstring()) -> integer(). main(Arg) -> case Arg of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards2.snap index 1e87cda3c..44c5ba9c5 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 420 expression: "\npub const constant = #(1, 2.0)\n\npub fn main(arg) {\n case arg {\n _ if arg == constant -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub const constant = #(1, 2.0)\n\npub fn main(arg) {\n case arg -export([main/1]). +-file("/root/project/test/my/mod.gleam", 4). -spec main({integer(), float()}) -> integer(). main(Arg) -> case Arg of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards3.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards3.snap index 56889dd95..18413f7ac 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards3.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__guards__only_guards3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/guards.rs +assertion_line: 436 expression: "\npub const float_value = 3.14\n\npub fn main(arg) {\n case arg {\n _ if arg >. float_value -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub const float_value = 3.14\n\npub fn main(arg) {\n case arg {\ -export([main/1]). +-file("/root/project/test/my/mod.gleam", 4). -spec main(float()) -> integer(). main(Arg) -> case Arg of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__more_than_one_var.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__more_than_one_var.snap index cbcfef291..1e77460c8 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__more_than_one_var.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__more_than_one_var.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/let_assert.rs +assertion_line: 17 expression: "pub fn go(x) {\n let assert [1, a, b, c] = x\n [a, b, c]\n}" --- -module(my@mod). @@ -7,13 +8,14 @@ expression: "pub fn go(x) {\n let assert [1, a, b, c] = x\n [a, b, c]\n}" -export([go/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec go(list(integer())) -> list(integer()). go(X) -> [1, A, B, C] = case X of [1, _, _, _] -> X; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"go"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__one_var.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__one_var.snap index afa71a97b..e20716204 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__one_var.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__one_var.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/let_assert.rs +assertion_line: 6 expression: "pub fn go() {\n let assert Ok(y) = Ok(1)\n y\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn go() {\n let assert Ok(y) = Ok(1)\n y\n}" -export([go/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec go() -> integer(). go() -> _assert_subject = {ok, 1}, @@ -14,7 +16,7 @@ go() -> {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"go"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__pattern_let.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__pattern_let.snap index ccd93047d..e041fc56e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__pattern_let.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__pattern_let.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/let_assert.rs +assertion_line: 28 expression: "pub fn go(x) {\n let assert [1 as a, b, c] = x\n [a, b, c]\n}" --- -module(my@mod). @@ -7,13 +8,14 @@ expression: "pub fn go(x) {\n let assert [1 as a, b, c] = x\n [a, b, c]\n}" -export([go/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec go(list(integer())) -> list(integer()). go(X) -> [1 = A, B, C] = case X of [1, _, _] -> X; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"go"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__variable_rewrites.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__variable_rewrites.snap index 2e9e52650..553f29ae0 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__variable_rewrites.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__let_assert__variable_rewrites.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/let_assert.rs +assertion_line: 39 expression: "pub fn go() {\n let assert Ok(y) = Ok(1)\n let assert Ok(y) = Ok(1)\n y\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn go() {\n let assert Ok(y) = Ok(1)\n let assert Ok(y) = Ok( -export([go/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec go() -> integer(). go() -> _assert_subject = {ok, 1}, @@ -14,7 +16,7 @@ go() -> {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"go"/utf8>>, @@ -25,7 +27,7 @@ go() -> {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail@1, module => <<"my/mod"/utf8>>, function => <<"go"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__int_negation.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__int_negation.snap index 7d5a8c4c9..774cfae53 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__int_negation.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__int_negation.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/numbers.rs +assertion_line: 69 expression: "\npub fn main() {\n let a = 3\n let b = -a\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let a = 3\n let b = -a\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> A = 3, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_scientific_notation.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_scientific_notation.snap index 0f1efd6d6..a0033118c 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_scientific_notation.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_scientific_notation.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/numbers.rs +assertion_line: 44 expression: "\nconst i = 100.001e523\nconst j = -100.001e-523\n\nconst k = 100.001e1_230\nconst l = -100.001e-1_230\n\nconst m = 100.001e123_456_789\nconst n = -100.001e-123_456_789\n\npub fn main() {\n i\n j\n k\n l\n m\n n\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nconst i = 100.001e523\nconst j = -100.001e-523\n\nconst k = 100.0 -export([main/0]). +-file("/root/project/test/my/mod.gleam", 11). -spec main() -> float(). main() -> 100.001e523, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores.snap index bc4543510..efdc6b013 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/numbers.rs +assertion_line: 5 expression: "\npub fn main() {\n 100_000\n 100_000.00101\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n 100_000\n 100_000.00101\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> float(). main() -> 100000, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores1.snap index 785a508fe..f73be931b 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/numbers.rs +assertion_line: 17 expression: "\nconst i = 100_000\nconst f = 100_000.00101\npub fn main() {\n i\n f\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nconst i = 100_000\nconst f = 100_000.00101\npub fn main() {\n i\ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> float(). main() -> 100000, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores2.snap index 086b1ca08..09aefe64e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__numbers_with_underscores2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/numbers.rs +assertion_line: 31 expression: "\npub fn main() {\n let assert 100_000 = 1\n let assert 100_000.00101 = 1.\n 1\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let assert 100_000 = 1\n let assert 100_000.0 -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> _assert_subject = 1, @@ -14,7 +16,7 @@ main() -> 100000 -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, @@ -25,7 +27,7 @@ main() -> 100000.00101 -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail@1, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__repeated_int_negation.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__repeated_int_negation.snap index 1ec4a2473..c22a71678 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__repeated_int_negation.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__repeated_int_negation.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/numbers.rs +assertion_line: 81 expression: "\npub fn main() {\n let a = 3\n let b = --a\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let a = 3\n let b = --a\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> A = 3, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__zero_b_in_hex.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__zero_b_in_hex.snap index 2efc0e717..8fad7f891 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__zero_b_in_hex.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__numbers__zero_b_in_hex.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/numbers.rs +assertion_line: 94 expression: "\npub fn main() {\n 0xffe0bb\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n 0xffe0bb\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> 16#ffe0bb. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__panic_as.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__panic_as.snap index 822e22e56..34462d880 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__panic_as.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__panic_as.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/panic.rs +assertion_line: 5 expression: "\npub fn main() {\n panic as \"wibble\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n panic as \"wibble\"\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> any(). main() -> erlang:error(#{gleam_error => panic, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__panic_as_function.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__panic_as_function.snap index c66bbb269..c18a27ef1 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__panic_as_function.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__panic_as_function.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/panic.rs +assertion_line: 27 expression: "\npub fn retstring() {\n \"wibble\"\n}\npub fn main() {\n panic as { retstring() <> \"wobble\" }\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\npub fn retstring() {\n \"wibble\"\n}\npub fn main() {\n panic a -export([retstring/0, main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec retstring() -> binary(). retstring() -> <<"wibble"/utf8>>. +-file("/root/project/test/my/mod.gleam", 5). -spec main() -> any(). main() -> erlang:error(#{gleam_error => panic, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__piped.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__piped.snap index a1610c5df..dac0fbb97 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__piped.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__piped.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/panic.rs +assertion_line: 42 expression: "\npub fn main() {\n \"lets\"\n |> panic\n}\n " --- -module(my@mod). @@ -7,11 +8,12 @@ expression: "\npub fn main() {\n \"lets\"\n |> panic\n}\n " -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> any(). main() -> _pipe = <<"lets"/utf8>>, (erlang:error(#{gleam_error => panic, - message => <<"panic expression evaluated"/utf8>>, + message => <<"`panic` expression evaluated."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, line => 4}))(_pipe). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__piped_chain.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__piped_chain.snap index 1c1cf5c8a..6a934d4f2 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__piped_chain.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__piped_chain.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/panic.rs +assertion_line: 54 expression: "\n pub fn main() {\n \"lets\"\n |> panic as \"pipe\"\n |> panic as \"other panic\"\n }\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n pub fn main() {\n \"lets\"\n |> panic as \"pipe\"\ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> any(). main() -> _pipe = <<"lets"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__plain.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__plain.snap index b6d6b5c3d..ac3c8d42d 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__plain.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__panic__plain.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/panic.rs +assertion_line: 16 expression: "\npub fn main() {\n panic\n}\n" --- -module(my@mod). @@ -7,10 +8,11 @@ expression: "\npub fn main() {\n panic\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> any(). main() -> erlang:error(#{gleam_error => panic, - message => <<"panic expression evaluated"/utf8>>, + message => <<"`panic` expression evaluated."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, line => 3}). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns.snap index 465ad325e..085a24d43 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/patterns.rs +assertion_line: 6 expression: "\npub fn main() {\n let duplicate_name = 1\n\n case 1 {\n 1 | 2 -> {\n let duplicate_name = duplicate_name + 1\n duplicate_name\n }\n _ -> 0\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let duplicate_name = 1\n\n case 1 {\n 1 | -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> Duplicate_name = 1, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns1.snap index 98879f6b3..8a5a3d14c 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/patterns.rs +assertion_line: 25 expression: "\npub fn main() {\n case Ok(1) {\n Ok(duplicate_name) | Error(duplicate_name) -> duplicate_name\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n case Ok(1) {\n Ok(duplicate_name) | Error(d -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> case {ok, 1} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns2.snap index 4057e8283..c94071bdc 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/patterns.rs +assertion_line: 38 expression: "\npub fn main() {\n let duplicate_name = 1\n\n case 1 {\n 1 | 2 if duplicate_name == 1 -> duplicate_name\n _ -> 0\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let duplicate_name = 1\n\n case 1 {\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> Duplicate_name = 1, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns3.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns3.snap index 69c3505f8..de7f51889 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns3.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__alternative_patterns3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/patterns.rs +assertion_line: 53 expression: "\npub const constant = Ok(1)\n\npub fn main(arg) {\n let _ = constant\n case arg {\n _ if arg == constant -> 1\n _ -> 0\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub const constant = Ok(1)\n\npub fn main(arg) {\n let _ = const -export([main/1]). +-file("/root/project/test/my/mod.gleam", 4). -spec main({ok, integer()} | {error, any()}) -> integer(). main(Arg) -> _ = {ok, 1}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__pattern_as.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__pattern_as.snap index bde59625b..518ec1cec 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__pattern_as.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__pattern_as.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/patterns.rs +assertion_line: 70 expression: "pub fn a(x) {\n case x {\n Ok(1 as y) -> 1\n _ -> 0\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn a(x) {\n case x {\n Ok(1 as y) -> 1\n _ -> 0\n }\n}" -export([a/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec a({ok, integer()} | {error, any()}) -> integer(). a(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_assertion.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_assertion.snap index d38a9f29b..adcc772fb 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_assertion.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_assertion.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/patterns.rs +assertion_line: 118 expression: "pub fn a(x) {\n let assert \"a\" as a <> rest = \"wibble\"\n a\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn a(x) {\n let assert \"a\" as a <> rest = \"wibble\"\n a\n} -export([a/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec a(any()) -> binary(). a(X) -> _assert_subject = <<"wibble"/utf8>>, @@ -14,7 +16,7 @@ a(X) -> <> when A =:= <<"a"/utf8>> -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"a"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_list.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_list.snap index 7c05bab83..ee435a56c 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_list.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_list.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/patterns.rs +assertion_line: 106 expression: "pub fn a(x) {\n case x {\n [\"a\" as a <> _, \"b\" as b <> _] -> a <> b\n _ -> \"\"\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn a(x) {\n case x {\n [\"a\" as a <> _, \"b\" as b <> _] - -export([a/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec a(list(binary())) -> binary(). a(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_multiple_subjects.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_multiple_subjects.snap index c9ce59859..04cc08a25 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_multiple_subjects.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_multiple_subjects.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/patterns.rs +assertion_line: 82 expression: "pub fn a(x) {\n case x, x {\n _, \"a\" as a <> _ -> a\n _, _ -> \"a\"\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn a(x) {\n case x, x {\n _, \"a\" as a <> _ -> a\n _, -export([a/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec a(binary()) -> binary(). a(X) -> case {X, X} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_multiple_subjects_and_guard.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_multiple_subjects_and_guard.snap index 2e7f966ea..582e1a33d 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_multiple_subjects_and_guard.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__patterns__string_prefix_as_pattern_with_multiple_subjects_and_guard.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/patterns.rs +assertion_line: 94 expression: "pub fn a(x) {\n case x, x {\n _, \"a\" as a <> rest if rest == \"a\" -> a\n _, _ -> \"a\"\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn a(x) {\n case x, x {\n _, \"a\" as a <> rest if rest == -export([a/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec a(binary()) -> binary(). a(X) -> case {X, X} of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__block_expr_into_pipe.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__block_expr_into_pipe.snap index 6f69fdea2..b387507a3 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__block_expr_into_pipe.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__block_expr_into_pipe.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/pipes.rs +assertion_line: 26 expression: "fn id(a) { a }\npub fn main() {\n {\n let x = 1\n x\n }\n |> id\n}" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "fn id(a) { a }\npub fn main() {\n {\n let x = 1\n x\n }\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec id(I) -> I. id(A) -> A. +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> _pipe = begin diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__call_pipeline_result.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__call_pipeline_result.snap index dc89bc806..59c1796fa 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__call_pipeline_result.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__call_pipeline_result.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/pipes.rs +assertion_line: 106 expression: "\npub fn main() {\n { 1 |> add }(1)\n}\n\npub fn add(x) {\n fn(y) { x + y }\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\npub fn main() {\n { 1 |> add }(1)\n}\n\npub fn add(x) {\n fn(y) -export([add/1, main/0]). +-file("/root/project/test/my/mod.gleam", 6). -spec add(integer()) -> fun((integer()) -> integer()). add(X) -> fun(Y) -> X + Y end. +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> begin diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__clever_pipe_rewriting.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__clever_pipe_rewriting.snap index 6eeecc500..43b5a6669 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__clever_pipe_rewriting.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__clever_pipe_rewriting.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/pipes.rs +assertion_line: 6 expression: "\npub fn apply(f: fn(a) -> b, a: a) { a |> f }\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn apply(f: fn(a) -> b, a: a) { a |> f }\n" -export([apply/2]). +-file("/root/project/test/my/mod.gleam", 2). -spec apply(fun((I) -> J), I) -> J. apply(F, A) -> _pipe = A, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__clever_pipe_rewriting1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__clever_pipe_rewriting1.snap index 484f563f3..f1ca2262f 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__clever_pipe_rewriting1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__clever_pipe_rewriting1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/pipes.rs +assertion_line: 16 expression: "\npub fn apply(f: fn(a, Int) -> b, a: a) { a |> f(1) }\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn apply(f: fn(a, Int) -> b, a: a) { a |> f(1) }\n" -export([apply/2]). +-file("/root/project/test/my/mod.gleam", 2). -spec apply(fun((I, integer()) -> J), I) -> J. apply(F, A) -> _pipe = A, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_call.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_call.snap index fbbbed9d2..7ce715206 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_call.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_call.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/pipes.rs +assertion_line: 122 expression: "\npub fn main() {\n 123\n |> two(\n 1 |> two(2),\n _,\n )\n}\n\npub fn two(a, b) {\n a\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\npub fn main() {\n 123\n |> two(\n 1 |> two(2),\n _,\n )\ -export([two/2, main/0]). +-file("/root/project/test/my/mod.gleam", 10). -spec two(J, any()) -> J. two(A, B) -> A. +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> _pipe = 123, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_case_subject.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_case_subject.snap index 08494a621..d6cb2344b 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_case_subject.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_case_subject.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/pipes.rs +assertion_line: 62 expression: "pub fn x(f) {\n case 1 |> f {\n x -> x\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn x(f) {\n case 1 |> f {\n x -> x\n }\n}" -export([x/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec x(fun((integer()) -> L)) -> L. x(F) -> case begin diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_eq.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_eq.snap index 2511a0cbf..664774ff2 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_eq.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_eq.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/pipes.rs +assertion_line: 92 expression: "fn id(x) {\n x\n}\n \npub fn main() {\n 1 == 1 |> id\n}" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "fn id(x) {\n x\n}\n \npub fn main() {\n 1 == 1 |> id\n}" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec id(I) -> I. id(X) -> X. +-file("/root/project/test/my/mod.gleam", 5). -spec main() -> boolean(). main() -> 1 =:= begin diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_list.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_list.snap index ad14087f5..4d29bd11e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_list.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_list.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/pipes.rs +assertion_line: 40 expression: "pub fn x(f) {\n [\n 1 |> f\n ]\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn x(f) {\n [\n 1 |> f\n ]\n}" -export([x/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec x(fun((integer()) -> L)) -> list(L). x(F) -> [begin diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_spread.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_spread.snap index f69145353..cb0d772af 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_spread.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_spread.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/pipes.rs +assertion_line: 74 expression: "pub type X {\n X(a: Int, b: Int)\n}\n\nfn id(x) {\n x\n}\n \npub fn main(x) {\n X(..x, a: 1 |> id)\n}" --- -module(my@mod). @@ -10,10 +11,12 @@ expression: "pub type X {\n X(a: Int, b: Int)\n}\n\nfn id(x) {\n x\n}\n -type x() :: {x, integer(), integer()}. +-file("/root/project/test/my/mod.gleam", 5). -spec id(I) -> I. id(X) -> X. +-file("/root/project/test/my/mod.gleam", 9). -spec main(x()) -> x(). main(X) -> erlang:setelement( diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_tuple.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_tuple.snap index d856b9e5d..34f4e0083 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_tuple.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__pipes__pipe_in_tuple.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/pipes.rs +assertion_line: 51 expression: "pub fn x(f) {\n #(\n 1 |> f\n )\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn x(f) {\n #(\n 1 |> f\n )\n}" -export([x/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec x(fun((integer()) -> K)) -> {K}. x(F) -> {begin diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__imported_qualified_constructor_as_fn_name_escape.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__imported_qualified_constructor_as_fn_name_escape.snap index 3d67b3d13..667db3158 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__imported_qualified_constructor_as_fn_name_escape.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__imported_qualified_constructor_as_fn_name_escape.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 358 expression: "import other_module\n\npub fn main() {\n other_module.Let\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "import other_module\n\npub fn main() {\n other_module.Let\n}" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 3). -spec main() -> fun((integer()) -> other_module:'let'()). main() -> fun(Field@0) -> {'let', Field@0} end. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__pipe_update_subject.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__pipe_update_subject.snap index ee98534cc..1534388e7 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__pipe_update_subject.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__pipe_update_subject.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 324 expression: "pub type Thing {\n Thing(a: Int, b: Int)\n}\n\npub fn identity(x) { x }\n\npub fn main() {\n let thing = Thing(1, 2)\n Thing(..thing |> identity, b: 1000)\n}" --- -module(my@mod). @@ -10,10 +11,12 @@ expression: "pub type Thing {\n Thing(a: Int, b: Int)\n}\n\npub fn identity(x) -type thing() :: {thing, integer(), integer()}. +-file("/root/project/test/my/mod.gleam", 5). -spec identity(I) -> I. identity(X) -> X. +-file("/root/project/test/my/mod.gleam", 7). -spec main() -> thing(). main() -> Thing = {thing, 1, 2}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_access_block.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_access_block.snap index 031233a29..9abb69a18 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_access_block.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_access_block.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 341 expression: "pub type Thing {\n Thing(a: Int, b: Int)\n}\n\npub fn main() {\n {\n let thing = Thing(1, 2)\n thing\n }.a\n}" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "pub type Thing {\n Thing(a: Int, b: Int)\n}\n\npub fn main() {\n -type thing() :: {thing, integer(), integer()}. +-file("/root/project/test/my/mod.gleam", 5). -spec main() -> integer(). main() -> erlang:element( diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants.snap index c08ffdbfc..786436ef0 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 100 expression: "\npub type Person {\n Teacher(name: String, title: String)\n Student(name: String, age: Int)\n}\npub fn get_name(person: Person) { person.name }" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\npub type Person {\n Teacher(name: String, title: String)\n -type person() :: {teacher, binary(), binary()} | {student, binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 6). -spec get_name(person()) -> binary(). get_name(Person) -> erlang:element(2, Person). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants_parameterised_types.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants_parameterised_types.snap index 5ccee2b94..8fb0e8cba 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants_parameterised_types.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants_parameterised_types.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 129 expression: "\npub type Person {\n Teacher(name: String, age: List(Int), title: String)\n Student(name: String, age: List(Int))\n}\npub fn get_name(person: Person) { person.name }\npub fn get_age(person: Person) { person.age }" --- -module(my@mod). @@ -11,10 +12,12 @@ expression: "\npub type Person {\n Teacher(name: String, age: List(Int), titl -type person() :: {teacher, binary(), list(integer()), binary()} | {student, binary(), list(integer())}. +-file("/root/project/test/my/mod.gleam", 6). -spec get_name(person()) -> binary(). get_name(Person) -> erlang:element(2, Person). +-file("/root/project/test/my/mod.gleam", 7). -spec get_age(person()) -> list(integer()). get_age(Person) -> erlang:element(3, Person). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants_positions_other_than_first.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants_positions_other_than_first.snap index f20603e24..9fa7c29dd 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants_positions_other_than_first.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_variants_positions_other_than_first.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 114 expression: "\npub type Person {\n Teacher(name: String, age: Int, title: String)\n Student(name: String, age: Int)\n}\npub fn get_name(person: Person) { person.name }\npub fn get_age(person: Person) { person.age }" --- -module(my@mod). @@ -11,10 +12,12 @@ expression: "\npub type Person {\n Teacher(name: String, age: Int, title: Str -type person() :: {teacher, binary(), integer(), binary()} | {student, binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 6). -spec get_name(person()) -> binary(). get_name(Person) -> erlang:element(2, Person). +-file("/root/project/test/my/mod.gleam", 7). -spec get_age(person()) -> integer(). get_age(Person) -> erlang:element(3, Person). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_with_first_position_different_types.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_with_first_position_different_types.snap index 5c9943b88..a62423545 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_with_first_position_different_types.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessor_multiple_with_first_position_different_types.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 144 expression: "\npub type Person {\n Teacher(name: Nil, age: Int)\n Student(name: String, age: Int)\n}\npub fn get_age(person: Person) { person.age }" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "\npub type Person {\n Teacher(name: Nil, age: Int)\n Student( -type person() :: {teacher, nil, integer()} | {student, binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 6). -spec get_age(person()) -> integer(). get_age(Person) -> erlang:element(3, Person). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessors.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessors.snap index 27f3cea28..b46ef42a3 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessors.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_accessors.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 88 expression: "\npub type Person { Person(name: String, age: Int) }\npub fn get_age(person: Person) { person.age }\npub fn get_name(person: Person) { person.name }\n" --- -module(my@mod). @@ -10,10 +11,12 @@ expression: "\npub type Person { Person(name: String, age: Int) }\npub fn get_ag -type person() :: {person, binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 3). -spec get_age(person()) -> integer(). get_age(Person) -> erlang:element(3, Person). +-file("/root/project/test/my/mod.gleam", 4). -spec get_name(person()) -> binary(). get_name(Person) -> erlang:element(2, Person). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_constants.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_constants.snap index d6a453372..26921e678 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_constants.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_constants.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 314 expression: "pub type Test { A }\nconst some_test = A\npub fn a() { A }" --- -module(my@mod). @@ -10,6 +11,7 @@ expression: "pub type Test { A }\nconst some_test = A\npub fn a() { A }" -type test() :: a. +-file("/root/project/test/my/mod.gleam", 3). -spec a() -> test(). a() -> a. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread.snap index 5ba321409..dd54a61df 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 157 expression: "\ntype Triple {\n Triple(a: Int, b: Int, c: Int)\n}\n\nfn main() {\n let triple = Triple(1,2,3)\n let Triple(the_a, ..) = triple\n the_a\n}\n" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "\ntype Triple {\n Triple(a: Int, b: Int, c: Int)\n}\n\nfn main() -type triple() :: {triple, integer(), integer(), integer()}. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> integer(). main() -> Triple = {triple, 1, 2, 3}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread1.snap index a08c84f7b..484caeda4 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 176 expression: "\ntype Triple {\n Triple(a: Int, b: Int, c: Int)\n}\n\nfn main() {\n let triple = Triple(1,2,3)\n let Triple(b: the_b, ..) = triple\n the_b\n}\n" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "\ntype Triple {\n Triple(a: Int, b: Int, c: Int)\n}\n\nfn main() { -type triple() :: {triple, integer(), integer(), integer()}. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> integer(). main() -> Triple = {triple, 1, 2, 3}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread2.snap index 7abdbab95..143dab981 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 194 expression: "\ntype Triple {\n Triple(a: Int, b: Int, c: Int)\n}\n\nfn main() {\n let triple = Triple(1,2,3)\n let Triple(the_a, c: the_c, ..) = triple\n the_c\n}\n" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "\ntype Triple {\n Triple(a: Int, b: Int, c: Int)\n}\n\nfn main() { -type triple() :: {triple, integer(), integer(), integer()}. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> integer(). main() -> Triple = {triple, 1, 2, 3}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread3.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread3.snap index c53faa607..d8b0ae0ed 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread3.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_spread3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 212 expression: "\ntype Triple {\n Triple(a: Int, b: Int, c: Int)\n}\n\nfn main() {\n let triple = Triple(1,2,3)\n case triple {\n Triple(b: the_b, ..) -> the_b\n }\n}\n" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "\ntype Triple {\n Triple(a: Int, b: Int, c: Int)\n}\n\nfn main() { -type triple() :: {triple, integer(), integer(), integer()}. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> integer(). main() -> Triple = {triple, 1, 2, 3}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates.snap index 5fad77e96..913a202aa 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 231 expression: "\npub type Person { Person(name: String, age: Int) }\n\nfn main() {\n let p = Person(\"Quinn\", 27)\n let new_p = Person(..p, age: 28)\n new_p\n}\n" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "\npub type Person { Person(name: String, age: Int) }\n\nfn main() { -type person() :: {person, binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> person(). main() -> P = {person, <<"Quinn"/utf8>>, 27}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates1.snap index 93f2fe92d..36843b213 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 247 expression: "\npub type Person { Person(name: String, age: Int) }\n\nfn main() {\n let p = Person(\"Quinn\", 27)\n let new_p = Person(..p, age: p.age + 1)\n new_p\n}\n" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "\npub type Person { Person(name: String, age: Int) }\n\nfn main() { -type person() :: {person, binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> person(). main() -> P = {person, <<"Quinn"/utf8>>, 27}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates2.snap index e692b0034..4f7e946c7 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 263 expression: "\npub type Person { Person(name: String, age: Int) }\n\nfn main() {\n let p = Person(\"Quinn\", 27)\n let new_p = Person(..p, age: 28, name: \"Riley\")\n new_p\n}\n" --- -module(my@mod). @@ -9,6 +10,7 @@ expression: "\npub type Person { Person(name: String, age: Int) }\n\nfn main() { -type person() :: {person, binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> person(). main() -> P = {person, <<"Quinn"/utf8>>, 27}, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates3.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates3.snap index f00e55ea3..9e0cca4d6 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates3.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 279 expression: "\npub type Person { Person(name: String, age: Int) }\n\nfn main() {\n let new_p = Person(..return_person(), age: 28)\n new_p\n}\n\nfn return_person() {\n Person(\"Quinn\", 27)\n}\n" --- -module(my@mod). @@ -9,10 +10,12 @@ expression: "\npub type Person { Person(name: String, age: Int) }\n\nfn main() { -type person() :: {person, binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 9). -spec return_person() -> person(). return_person() -> {person, <<"Quinn"/utf8>>, 27}. +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> person(). main() -> New_p = erlang:setelement(3, return_person(), 28), diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates4.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates4.snap index e941e9df4..cbfdcd6f1 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates4.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__records__record_updates4.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/records.rs +assertion_line: 298 expression: "\npub type Car { Car(make: String, model: String, driver: Person) }\npub type Person { Person(name: String, age: Int) }\n\nfn main() {\n let car = Car(make: \"Amphicar\", model: \"Model 770\", driver: Person(name: \"John Doe\", age: 27))\n let new_p = Person(..car.driver, age: 28)\n new_p\n}\n" --- -module(my@mod). @@ -11,6 +12,7 @@ expression: "\npub type Car { Car(make: String, model: String, driver: Person) } -type person() :: {person, binary(), integer()}. +-file("/root/project/test/my/mod.gleam", 5). -spec main() -> person(). main() -> Car = {car, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__ascii_as_unicode_escape_sequence.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__ascii_as_unicode_escape_sequence.snap index 23d3f7686..a5da377f1 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__ascii_as_unicode_escape_sequence.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__ascii_as_unicode_escape_sequence.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 106 expression: "\npub fn y() -> String {\n \"\\u{79}\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn y() -> String {\n \"\\u{79}\"\n}\n" -export([y/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec y() -> binary(). y() -> <<"\x{79}"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat.snap index afca57561..0449d30b9 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 444 expression: "\nconst cute = \"cute\"\nconst cute_bee = cute <> \"bee\"\n\npub fn main() {\n cute_bee\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nconst cute = \"cute\"\nconst cute_bee = cute <> \"bee\"\n\npub fn -export([main/0]). +-file("/root/project/test/my/mod.gleam", 5). -spec main() -> binary(). main() -> <<"cute"/utf8, "bee"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_many_strings.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_many_strings.snap index a67d20317..e8f4accfb 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_many_strings.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_many_strings.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 458 expression: "\nconst big_concat = \"a\" <> \"b\" <> \"c\" <> \"d\" <> \"e\" <> \"f\" <> \"g\" <> \"h\" <> \"i\" <> \"j\" <> \"k\" <> \"l\" <> \"m\" <> \"n\" <> \"o\" <> \"p\" <> \"q\" <> \"r\" <> \"s\" <> \"t\" <> \"u\" <> \"v\" <> \"w\" <> \"x\" <> \"y\" <> \"z\"\n\npub fn main() {\n big_concat\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nconst big_concat = \"a\" <> \"b\" <> \"c\" <> \"d\" <> \"e\" <> \ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> binary(). main() -> <<"a"/utf8, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_many_strings_in_list.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_many_strings_in_list.snap index 107ce71d3..2f661c1e1 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_many_strings_in_list.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_many_strings_in_list.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 471 expression: "\nconst big_concat_list = [\"a\" <> \"b\" <> \"c\" <> \"d\" <> \"e\" <> \"f\" <> \"g\" <> \"h\" <> \"i\" <> \"j\" <> \"k\" <> \"l\" <> \"m\" <> \"n\" <> \"o\" <> \"p\" <> \"q\" <> \"r\" <> \"s\" <> \"t\" <> \"u\" <> \"v\" <> \"w\" <> \"x\" <> \"y\" <> \"z\"]\n\npub fn main() {\n big_concat_list\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nconst big_concat_list = [\"a\" <> \"b\" <> \"c\" <> \"d\" <> \"e\ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec main() -> list(binary()). main() -> [<<"a"/utf8, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_other_const_concat.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_other_const_concat.snap index 293b334a1..074935ce2 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_other_const_concat.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_const_concat_other_const_concat.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 484 expression: "\nconst cute_bee = \"cute\" <> \"bee\"\nconst cute_cute_bee_buzz = cute_bee <> \"buzz\"\n\npub fn main() {\n cute_cute_bee_buzz\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nconst cute_bee = \"cute\" <> \"bee\"\nconst cute_cute_bee_buzz = -export([main/0]). +-file("/root/project/test/my/mod.gleam", 5). -spec main() -> binary(). main() -> <<"cute"/utf8, "bee"/utf8, "buzz"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_string_prefix.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_string_prefix.snap index 1f226194b..80f95ea2b 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_string_prefix.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_string_prefix.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 421 expression: "\npub fn main(x) {\n let assert \"m-\" <> rest = x\n rest\n}\n" --- -module(my@mod). @@ -7,13 +8,14 @@ expression: "\npub fn main(x) {\n let assert \"m-\" <> rest = x\n rest\n}\n" -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(binary()) -> binary(). main(X) -> <<"m-"/utf8, Rest/binary>> = case X of <<"m-"/utf8, _/binary>> -> X; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_string_prefix_discar.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_string_prefix_discar.snap index ab6a8372d..1c219686f 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_string_prefix_discar.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__assert_string_prefix_discar.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 433 expression: "\npub fn main(x) {\n let assert \"m-\" <> _ = x\n}\n" --- -module(my@mod). @@ -7,13 +8,14 @@ expression: "\npub fn main(x) {\n let assert \"m-\" <> _ = x\n}\n" -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(binary()) -> binary(). main(X) -> <<"m-"/utf8, _/binary>> = case X of <<"m-"/utf8, _/binary>> -> X; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat.snap index 06fcfc806..822e7da53 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 117 expression: "\npub fn go(x, y) {\n x <> y\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x, y) {\n x <> y\n}\n" -export([go/2]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary(), binary()) -> binary(). go(X, Y) -> <>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_3_variables.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_3_variables.snap index f00456d70..d689a8661 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_3_variables.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_3_variables.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 128 expression: "\npub fn go(x, y, z) {\n x <> y <> z\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x, y, z) {\n x <> y <> z\n}\n" -export([go/3]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary(), binary(), binary()) -> binary(). go(X, Y, Z) -> <<<>/binary, Z/binary>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_constant.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_constant.snap index 26893bc44..6a594c75e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_constant.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_constant.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 375 expression: "\nconst a = \"Hello, \"\nconst b = \"Joe!\"\n\npub fn go() {\n a <> b\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\nconst a = \"Hello, \"\nconst b = \"Joe!\"\n\npub fn go() {\n a < -export([go/0]). +-file("/root/project/test/my/mod.gleam", 5). -spec go() -> binary(). go() -> <<"Hello, "/utf8, "Joe!"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_constant_fn.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_constant_fn.snap index 558d3dfc5..98d9ef98e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_constant_fn.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_constant_fn.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 389 expression: "\nconst cs = s\n\nfn s() {\n \"s\"\n}\n\npub fn go() {\n cs() <> cs()\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\nconst cs = s\n\nfn s() {\n \"s\"\n}\n\npub fn go() {\n cs() <> -export([go/0]). +-file("/root/project/test/my/mod.gleam", 4). -spec s() -> binary(). s() -> <<"s"/utf8>>. +-file("/root/project/test/my/mod.gleam", 8). -spec go() -> binary(). go() -> <<(s())/binary, (s())/binary>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_function_call.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_function_call.snap index 349693f4c..b252d2cfb 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_function_call.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__concat_function_call.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 360 expression: "\nfn x() {\n \"\"\n}\n\npub fn go() {\n x() <> x()\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\nfn x() {\n \"\"\n}\n\npub fn go() {\n x() <> x()\n}\n" -export([go/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec x() -> binary(). x() -> <<""/utf8>>. +-file("/root/project/test/my/mod.gleam", 6). -spec go() -> binary(). go() -> <<(x())/binary, (x())/binary>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__discard_concat_rest_pattern.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__discard_concat_rest_pattern.snap index 1d16d874e..0ed12d9d7 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__discard_concat_rest_pattern.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__discard_concat_rest_pattern.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 335 expression: "\npub fn go(x) {\n case x {\n \"Hello, \" <> _ -> Nil\n _ -> Nil\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n case x {\n \"Hello, \" <> _ -> Nil\n _ -> -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> nil. go(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__not_unicode_escape_sequence.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__not_unicode_escape_sequence.snap index d91090410..156f58f05 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__not_unicode_escape_sequence.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__not_unicode_escape_sequence.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 62 expression: "\npub fn not_unicode_escape_sequence() -> String {\n \"\\\\u{03a9}\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn not_unicode_escape_sequence() -> String {\n \"\\\\u{03a9} -export([not_unicode_escape_sequence/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec not_unicode_escape_sequence() -> binary(). not_unicode_escape_sequence() -> <<"\\u{03a9}"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__not_unicode_escape_sequence2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__not_unicode_escape_sequence2.snap index 5326183e5..7a8271902 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__not_unicode_escape_sequence2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__not_unicode_escape_sequence2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 73 expression: "\npub fn not_unicode_escape_sequence() -> String {\n \"\\\\\\\\u{03a9}\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn not_unicode_escape_sequence() -> String {\n \"\\\\\\\\u{0 -export([not_unicode_escape_sequence/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec not_unicode_escape_sequence() -> binary(). not_unicode_escape_sequence() -> <<"\\\\u{03a9}"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__pipe_concat.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__pipe_concat.snap index 02b236079..26a7f19ed 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__pipe_concat.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__pipe_concat.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 406 expression: "\nfn id(x) {\n x\n}\n\npub fn main() {\n { \"\" |> id } <> { \"\" |> id }\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\nfn id(x) {\n x\n}\n\npub fn main() {\n { \"\" |> id } <> { \"\" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec id(I) -> I. id(X) -> X. +-file("/root/project/test/my/mod.gleam", 6). -spec main() -> binary(). main() -> <<(begin diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__rest_variable_rewriting.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__rest_variable_rewriting.snap index 93a9c7809..9854fa737 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__rest_variable_rewriting.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__rest_variable_rewriting.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 320 expression: "\npub fn go(x) {\n case x {\n \"Hello, \" <> x -> x\n _ -> \"Unknown\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n case x {\n \"Hello, \" <> x -> x\n _ -> \ -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_of_number_concat.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_of_number_concat.snap index efe2ca685..ca2ca8d24 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_of_number_concat.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_of_number_concat.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 349 expression: "\npub fn go(x) {\n x <> \"1\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n x <> \"1\"\n}\n" -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> <>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix.snap index a5cb269fa..b6c35529a 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 139 expression: "\npub fn go(x) {\n case x {\n \"Hello, \" <> name -> name\n _ -> \"Unknown\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n case x {\n \"Hello, \" <> name -> name\n -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment.snap index 4c02894fd..9114e9a76 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 153 expression: "\npub fn go(x) {\n case x {\n \"Hello, \" as greeting <> name -> greeting\n _ -> \"Unknown\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n case x {\n \"Hello, \" as greeting <> name - -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_not_unicode_escape_sequence.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_not_unicode_escape_sequence.snap index 4bed16549..3292f9826 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_not_unicode_escape_sequence.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_not_unicode_escape_sequence.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 243 expression: "\npub fn go(x) {\n let _ = case x {\n \"\\\\u{9}\" as start <> rest -> \"test\"\n \"\\\\u{000009}\" as start <> rest -> \"test\"\n \"\\\\u{21}\" as start <> rest -> \"test\"\n \"\\\\u{100}\" as start <> rest -> \"test\"\n \"\\\\u{1000}\" as start <> rest -> \"test\"\n \"\\\\u{1F600}\" as start <> rest -> \"test\"\n \"\\\\u{1f600}\" as start <> rest -> \"test\"\n \"\\\\u{01F600}\" as start <> rest -> \"test\"\n \"\\\\u{01f600}\" as start <> rest -> \"test\"\n \"\\\\u{9} \\\\u{000009} \\\\u{21} \\\\u{100} \\\\u{1000} \\\\u{1F600} \\\\u{01F600}\" as start <> rest -> \"test\"\n _ -> \"Unknown\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n let _ = case x {\n \"\\\\u{9}\" as start <> -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> _ = case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_escape_sequences.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_escape_sequences.snap index 5513d1c86..01c45e489 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_escape_sequences.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_escape_sequences.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 183 expression: "\npub fn go(x) {\n let _ = case x {\n \"\\f\" as start <> rest -> \"test\"\n \"\\n\" as start <> rest -> \"test\"\n \"\\r\" as start <> rest -> \"test\"\n \"\\t\" as start <> rest -> \"test\"\n \"\\\"\" as start <> rest -> \"test\"\n \"\\\\\" as start <> rest -> \"test\"\n \"\\f \\n \\r \\t \\\" \\\\\" as start <> rest -> \"control chars with prefix assignment\"\n \"\\u{9}\" as start <> rest -> \"test\"\n \"\\u{000009}\" as start <> rest -> \"test\"\n \"\\u{21}\" as start <> rest -> \"test\"\n \"\\u{100}\" as start <> rest -> \"test\"\n \"\\u{1000}\" as start <> rest -> \"test\"\n \"\\u{1F600}\" as start <> rest -> \"test\"\n \"\\u{1f600}\" as start <> rest -> \"test\"\n \"\\u{01F600}\" as start <> rest -> \"test\"\n \"\\u{01f600}\" as start <> rest -> \"test\"\n \"\\u{9} \\u{000009} \\u{21} \\u{100} \\u{1000} \\u{1F600} \\u{01F600}\" as start <> rest -> \"test\"\n _ -> \"Unknown\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n let _ = case x {\n \"\\f\" as start <> rest -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> _ = case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_guard.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_guard.snap index 5be11ccce..6b1cf9b2e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_guard.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_guard.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 167 expression: "\npub fn go(x) {\n case x {\n \"Hello, \" as greeting <> name if name == \"Dude\" -> greeting <> \"Mate\"\n \"Hello, \" as greeting <> name -> greeting\n _ -> \"Unknown\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n case x {\n \"Hello, \" as greeting <> name i -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_multiple_subjects.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_multiple_subjects.snap index c32dd8881..2a3a5d740 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_multiple_subjects.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_assignment_with_multiple_subjects.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 290 expression: "\npub fn go(x) {\n case x {\n \"1\" as digit <> _ | \"2\" as digit <> _ -> digit\n _ -> \"Unknown\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n case x {\n \"1\" as digit <> _ | \"2\" as di -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_not_unicode_escape_sequence.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_not_unicode_escape_sequence.snap index ecf3adba0..073608c0d 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_not_unicode_escape_sequence.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_not_unicode_escape_sequence.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 266 expression: "\npub fn go(x) {\n let _ = case x {\n \"\\\\u{9}\" <> rest -> \"test\"\n \"\\\\u{000009}\" <> rest -> \"test\"\n \"\\\\u{21}\" <> rest -> \"test\"\n \"\\\\u{100}\" <> rest -> \"test\"\n \"\\\\u{1000}\" <> rest -> \"test\"\n \"\\\\u{1F600}\" <> rest -> \"test\"\n \"\\\\u{1f600}\" <> rest -> \"test\"\n \"\\\\u{01F600}\" <> rest -> \"test\"\n \"\\\\u{01f600}\" <> rest -> \"test\"\n \"\\\\u{9} \\\\u{000009} \\\\u{21} \\\\u{100} \\\\u{1000} \\\\u{1F600} \\\\u{01F600}\" <> rest -> \"test\"\n _ -> \"Unknown\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n let _ = case x {\n \"\\\\u{9}\" <> rest -> \ -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> _ = case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_shadowing.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_shadowing.snap index da9dd1181..e5be459a3 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_shadowing.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_shadowing.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 304 expression: "\npub fn go(x) {\n case x {\n \"Hello, \" as x <> name -> x\n _ -> \"Unknown\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n case x {\n \"Hello, \" as x <> name -> x\n -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_with_escape_sequences.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_with_escape_sequences.snap index 95131f401..4bca20d00 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_with_escape_sequences.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__string_prefix_with_escape_sequences.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 213 expression: "\npub fn go(x) {\n let _ = case x {\n \"\\f\" <> rest -> \"test\"\n \"\\n\" <> rest -> \"test\"\n \"\\r\" <> rest -> \"test\"\n \"\\t\" <> rest -> \"test\"\n \"\\\"\" <> rest -> \"test\"\n \"\\\\\" <> rest -> \"test\"\n \"\\f \\n \\r \\t \\\" \\\\\" <> rest -> \"control chars with prefix assignment\"\n \"\\u{9}\" <> rest -> \"test\"\n \"\\u{000009}\" <> rest -> \"test\"\n \"\\u{21}\" <> rest -> \"test\"\n \"\\u{100}\" <> rest -> \"test\"\n \"\\u{1000}\" <> rest -> \"test\"\n \"\\u{1F600}\" <> rest -> \"test\"\n \"\\u{1f600}\" <> rest -> \"test\"\n \"\\u{01F600}\" <> rest -> \"test\"\n \"\\u{01f600}\" <> rest -> \"test\"\n \"\\u{9} \\u{000009} \\u{21} \\u{100} \\u{1000} \\u{1F600} \\u{01F600}\" <> rest -> \"test\"\n _ -> \"Unknown\"\n }\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(x) {\n let _ = case x {\n \"\\f\" <> rest -> \"test -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(binary()) -> binary(). go(X) -> _ = case X of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode1.snap index 42a9f193e..cdd7645cf 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 5 expression: "\npub fn emoji() -> String {\n \"\\u{1f600}\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn emoji() -> String {\n \"\\u{1f600}\"\n}\n" -export([emoji/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec emoji() -> binary(). emoji() -> <<"\x{1f600}"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode2.snap index 8c8d35efc..49eb6fcf0 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 16 expression: "\npub fn y_with_dieresis() -> String {\n \"\\u{0308}y\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn y_with_dieresis() -> String {\n \"\\u{0308}y\"\n}\n" -export([y_with_dieresis/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec y_with_dieresis() -> binary(). y_with_dieresis() -> <<"\x{0308}y"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode3.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode3.snap index 03d2c1788..2c002333f 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode3.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 84 expression: "\npub fn y_with_dieresis_with_slash() -> String {\n \"\\\\\\u{0308}y\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn y_with_dieresis_with_slash() -> String {\n \"\\\\\\u{0308 -export([y_with_dieresis_with_slash/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec y_with_dieresis_with_slash() -> binary(). y_with_dieresis_with_slash() -> <<"\\\x{0308}y"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat1.snap index 6b7d98cc6..4329ed363 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 27 expression: "\npub fn main(x) -> String {\n x <> \"\\u{0308}\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(x) -> String {\n x <> \"\\u{0308}\"\n}\n" -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(binary()) -> binary(). main(X) -> <>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat2.snap index 5a2b5de14..ee7bf5052 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 38 expression: "\npub fn main(x) -> String {\n x <> \"\\\\u{0308}\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(x) -> String {\n x <> \"\\\\u{0308}\"\n}\n" -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(binary()) -> binary(). main(X) -> <>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat3.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat3.snap index 8a9b997af..f7955a703 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat3.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_concat3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 49 expression: "\npub fn main(x) -> String {\n x <> \"\\\\\\u{0308}\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(x) -> String {\n x <> \"\\\\\\u{0308}\"\n}\n" -export([main/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec main(binary()) -> binary(). main(X) -> <>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_escape_sequence_6_digits.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_escape_sequence_6_digits.snap index 0d1e4ee55..b5564ae91 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_escape_sequence_6_digits.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__strings__unicode_escape_sequence_6_digits.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/strings.rs +assertion_line: 95 expression: "\npub fn unicode_escape_sequence_6_digits() -> String {\n \"\\u{10abcd}\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn unicode_escape_sequence_6_digits() -> String {\n \"\\u{10 -export([unicode_escape_sequence_6_digits/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec unicode_escape_sequence_6_digits() -> binary(). unicode_escape_sequence_6_digits() -> <<"\x{10abcd}"/utf8>>. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__named.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__named.snap index a87cebe9a..d495ec10e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__named.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__named.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/todo.rs +assertion_line: 27 expression: "\npub fn main() {\n todo as \"testing\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n todo as \"testing\"\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> any(). main() -> erlang:error(#{gleam_error => todo, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__piped.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__piped.snap index 0630ee3b1..adfd86c5b 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__piped.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__piped.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/todo.rs +assertion_line: 52 expression: "\n pub fn main() {\n \"lets\"\n |> todo as \"pipe\"\n |> todo as \"other todo\"\n }\n " --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n pub fn main() {\n \"lets\"\n |> todo as \"pipe\"\n -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> any(). main() -> _pipe = <<"lets"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__plain.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__plain.snap index 1d69c85c7..aa1725616 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__plain.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__plain.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/todo.rs +assertion_line: 5 expression: "\npub fn main() {\n todo\n}\n" --- -module(my@mod). @@ -7,10 +8,11 @@ expression: "\npub fn main() {\n todo\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> any(). main() -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, line => 3}). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__todo_as.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__todo_as.snap index a9c1fdfcb..9307c5295 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__todo_as.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__todo_as.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/todo.rs +assertion_line: 16 expression: "\npub fn main() {\n todo as \"wibble\"\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n todo as \"wibble\"\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> any(). main() -> erlang:error(#{gleam_error => todo, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__todo_as_function.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__todo_as_function.snap index 48989e8f1..0a0aa4800 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__todo_as_function.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__todo__todo_as_function.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/todo.rs +assertion_line: 38 expression: "\npub fn retstring() {\n \"wibble\"\n}\npub fn main() {\n todo as { retstring() <> \"wobble\" }\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\npub fn retstring() {\n \"wibble\"\n}\npub fn main() {\n todo as -export([retstring/0, main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec retstring() -> binary(). retstring() -> <<"wibble"/utf8>>. +-file("/root/project/test/my/mod.gleam", 5). -spec main() -> any(). main() -> erlang:error(#{gleam_error => todo, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_named_args_count_once.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_named_args_count_once.snap index 41cd88b3d..88f7a317d 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_named_args_count_once.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_named_args_count_once.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/type_params.rs +assertion_line: 72 expression: "\n pub type Wibble(a, b) {\n Wibble(a, b)\n }\n\n pub fn wibble() -> Wibble(a, a) {\n todo\n }\n " --- -module(my@mod). @@ -10,10 +11,11 @@ expression: "\n pub type Wibble(a, b) {\n Wibble(a, b)\n -type wibble(I, J) :: {wibble, I, J}. +-file("/root/project/test/my/mod.gleam", 6). -spec wibble() -> wibble(K, K). wibble() -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"wibble"/utf8>>, line => 7}). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_nested_named_args_count_once.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_nested_named_args_count_once.snap index 159c5a2eb..3d249be3c 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_nested_named_args_count_once.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_nested_named_args_count_once.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/type_params.rs +assertion_line: 87 expression: "\n pub type Wibble(a, b) {\n Wibble(a, b)\n }\n\n pub fn wibble() -> Wibble(a, Wibble(a, b)) {\n todo\n }\n " --- -module(my@mod). @@ -10,10 +11,11 @@ expression: "\n pub type Wibble(a, b) {\n Wibble(a, b)\n -type wibble(I, J) :: {wibble, I, J}. +-file("/root/project/test/my/mod.gleam", 6). -spec wibble() -> wibble(K, wibble(K, any())). wibble() -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"wibble"/utf8>>, line => 7}). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_nested_result_type_count_once.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_nested_result_type_count_once.snap index 5f65a2eba..a879bc98a 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_nested_result_type_count_once.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_nested_result_type_count_once.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/type_params.rs +assertion_line: 46 expression: "\n pub type Wibble(a) {\n Oops\n }\n\n pub fn wibble() -> Result(a, Wibble(a)) {\n todo\n }\n " --- -module(my@mod). @@ -10,10 +11,11 @@ expression: "\n pub type Wibble(a) {\n Oops\n }\n\n -type wibble(I) :: oops | {gleam_phantom, I}. +-file("/root/project/test/my/mod.gleam", 6). -spec wibble() -> {ok, any()} | {error, wibble(any())}. wibble() -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"wibble"/utf8>>, line => 7}). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_tuple_type_params_count_twice.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_tuple_type_params_count_twice.snap index 4b0d7b0f2..308afdc67 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_tuple_type_params_count_twice.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__custom_type_tuple_type_params_count_twice.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/type_params.rs +assertion_line: 102 expression: "\n pub type Wibble(a, b) {\n Wibble(a, b)\n }\n\n pub fn wibble() -> #(a, Wibble(a, b)) {\n todo\n }\n " --- -module(my@mod). @@ -10,10 +11,11 @@ expression: "\n pub type Wibble(a, b) {\n Wibble(a, b)\n -type wibble(I, J) :: {wibble, I, J}. +-file("/root/project/test/my/mod.gleam", 6). -spec wibble() -> {K, wibble(K, any())}. wibble() -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"wibble"/utf8>>, line => 7}). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__nested_result_type_count_once.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__nested_result_type_count_once.snap index 6e741769b..3e9d7ce6c 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__nested_result_type_count_once.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__nested_result_type_count_once.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/type_params.rs +assertion_line: 35 expression: "\n pub fn wibble() -> Result(a, Result(a, b)) {\n todo\n }\n " --- -module(my@mod). @@ -7,10 +8,11 @@ expression: "\n pub fn wibble() -> Result(a, Result(a, b)) {\n -export([wibble/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec wibble() -> {ok, any()} | {error, {ok, any()} | {error, any()}}. wibble() -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"wibble"/utf8>>, line => 3}). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__result_type_count_once.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__result_type_count_once.snap index cdac2ea5c..a9decf1ac 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__result_type_count_once.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__result_type_count_once.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/type_params.rs +assertion_line: 24 expression: "\n pub fn wibble() -> Result(a, a) {\n todo\n }\n " --- -module(my@mod). @@ -7,10 +8,11 @@ expression: "\n pub fn wibble() -> Result(a, a) {\n todo\n -export([wibble/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec wibble() -> {ok, any()} | {error, any()}. wibble() -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"wibble"/utf8>>, line => 3}). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__result_type_inferred_count_once.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__result_type_inferred_count_once.snap index e38e38f46..e4f932c71 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__result_type_inferred_count_once.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__result_type_inferred_count_once.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/type_params.rs +assertion_line: 5 expression: "\n fn wibble() {\n let assert Ok(_) = wobble()\n }\n\n type Wobble(a) {\n Wobble\n }\n\n fn wobble() -> Result(a, Wobble(a)) {\n todo\n }\n " --- -module(my@mod). @@ -9,14 +10,16 @@ expression: "\n fn wibble() {\n let assert Ok(_) = wobble()\n -type wobble(I) :: wobble | {gleam_phantom, I}. +-file("/root/project/test/my/mod.gleam", 10). -spec wobble() -> {ok, any()} | {error, wobble(any())}. wobble() -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"wobble"/utf8>>, line => 11}). +-file("/root/project/test/my/mod.gleam", 2). -spec wibble() -> {ok, any()} | {error, wobble(any())}. wibble() -> _assert_subject = wobble(), @@ -24,7 +27,7 @@ wibble() -> {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, + message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"my/mod"/utf8>>, function => <<"wibble"/utf8>>, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__tuple_type_params_count_twice.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__tuple_type_params_count_twice.snap index 58a556f6a..ed1934795 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__tuple_type_params_count_twice.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__type_params__tuple_type_params_count_twice.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/type_params.rs +assertion_line: 61 expression: "\n pub fn wibble() -> #(a, b) {\n todo\n }\n " --- -module(my@mod). @@ -7,10 +8,11 @@ expression: "\n pub fn wibble() -> #(a, b) {\n todo\n } -export([wibble/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec wibble() -> {any(), any()}. wibble() -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"wibble"/utf8>>, line => 3}). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_1.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_1.snap index b8cf5dc25..6ae209697 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_1.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/use_.rs +assertion_line: 5 expression: "\npub fn main() {\n use <- pair()\n 123\n}\n\nfn pair(f) {\n let x = f()\n #(x, x)\n}\n" --- -module(my@mod). @@ -7,11 +8,13 @@ expression: "\npub fn main() {\n use <- pair()\n 123\n}\n\nfn pair(f) {\n let -export([main/0]). +-file("/root/project/test/my/mod.gleam", 7). -spec pair(fun(() -> L)) -> {L, L}. pair(F) -> X = F(), {X, X}. +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> {integer(), integer()}. main() -> pair(fun() -> 123 end). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_2.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_2.snap index 5386bf9b0..faea9ed0d 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_2.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/use_.rs +assertion_line: 22 expression: "\npub fn main() {\n use <- pair(1.0)\n 123\n}\n\nfn pair(x, f) {\n let y = f()\n #(x, y)\n}\n" --- -module(my@mod). @@ -7,11 +8,13 @@ expression: "\npub fn main() {\n use <- pair(1.0)\n 123\n}\n\nfn pair(x, f) {\ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 7). -spec pair(J, fun(() -> M)) -> {J, M}. pair(X, F) -> Y = F(), {X, Y}. +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> {float(), integer()}. main() -> pair(1.0, fun() -> 123 end). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_3.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_3.snap index d41d413b6..b1da7d3f6 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_3.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___arity_3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/use_.rs +assertion_line: 39 expression: "\npub fn main() {\n use <- trip(1.0, \"\")\n 123\n}\n\nfn trip(x, y, f) {\n let z = f()\n #(x, y, z)\n}\n" --- -module(my@mod). @@ -7,11 +8,13 @@ expression: "\npub fn main() {\n use <- trip(1.0, \"\")\n 123\n}\n\nfn trip(x, -export([main/0]). +-file("/root/project/test/my/mod.gleam", 7). -spec trip(J, K, fun(() -> N)) -> {J, K, N}. trip(X, Y, F) -> Z = F(), {X, Y, Z}. +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> {float(), binary(), integer()}. main() -> trip(1.0, <<""/utf8>>, fun() -> 123 end). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___no_callback_body.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___no_callback_body.snap index b39a565aa..9c5614067 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___no_callback_body.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___no_callback_body.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/use_.rs +assertion_line: 56 expression: "\npub fn main() {\n let thingy = fn(f) { f() }\n use <- thingy()\n}\n" --- -module(my@mod). @@ -7,11 +8,12 @@ expression: "\npub fn main() {\n let thingy = fn(f) { f() }\n use <- thingy()\ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> any(). main() -> Thingy = fun(F) -> F() end, Thingy(fun() -> erlang:error(#{gleam_error => todo, - message => <<"This has not yet been implemented"/utf8>>, + message => <<"`todo` expression evaluated. This code has not yet been implemented."/utf8>>, module => <<"my/mod"/utf8>>, function => <<"main"/utf8>>, line => 4}) end). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___pipeline_that_returns_fn.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___pipeline_that_returns_fn.snap index 5d8513739..579171cc9 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___pipeline_that_returns_fn.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__use___pipeline_that_returns_fn.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/use_.rs +assertion_line: 69 expression: "\npub fn main() {\n use <- 1 |> add\n 1\n}\n\npub fn add(x) {\n fn(f) { f() + x }\n}\n" --- -module(my@mod). @@ -7,10 +8,12 @@ expression: "\npub fn main() {\n use <- 1 |> add\n 1\n}\n\npub fn add(x) {\n -export([add/1, main/0]). +-file("/root/project/test/my/mod.gleam", 7). -spec add(integer()) -> fun((fun(() -> integer())) -> integer()). add(X) -> fun(F) -> F() + X end. +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> begin diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__anon_external_fun_name_escaping.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__anon_external_fun_name_escaping.snap index ca176c29a..43fdef6bd 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__anon_external_fun_name_escaping.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__anon_external_fun_name_escaping.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/variables.rs +assertion_line: 70 expression: "\n@external(erlang, \"one.two\", \"three.four\")\nfn func() -> Nil\n\npub fn main() {\n func\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\n@external(erlang, \"one.two\", \"three.four\")\nfn func() -> Nil\ -export([main/0]). +-file("/root/project/test/my/mod.gleam", 5). -spec main() -> fun(() -> nil). main() -> fun 'one.two':'three.four'/0. diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__blocks_are_scopes.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__blocks_are_scopes.snap index 91f43537c..82c2307c9 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__blocks_are_scopes.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__blocks_are_scopes.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/variables.rs +assertion_line: 100 expression: "\npub fn main() {\n let x = 1\n {\n let x = 2\n }\n x\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main() {\n let x = 1\n {\n let x = 2\n }\n x\n}\n" -export([main/0]). +-file("/root/project/test/my/mod.gleam", 2). -spec main() -> integer(). main() -> X = 1, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__discarded.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__discarded.snap index 082f8059f..094ef2352 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__discarded.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__discarded.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/variables.rs +assertion_line: 58 expression: "pub fn go() {\n let _r = 1\n let _r = 2\n Nil\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn go() {\n let _r = 1\n let _r = 2\n Nil\n}" -export([go/0]). +-file("/root/project/test/my/mod.gleam", 1). -spec go() -> nil. go() -> _ = 1, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__module_const_vars.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__module_const_vars.snap index 81057aed5..0730dc74e 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__module_const_vars.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__module_const_vars.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/variables.rs +assertion_line: 83 expression: "const int = 42\nconst int_alias = int\npub fn use_int_alias() { int_alias }\n\nfn int_identity(i: Int) { i }\nconst int_identity_alias: fn(Int) -> Int = int_identity\npub fn use_int_identity_alias() { int_identity_alias(42) }\n\nconst compound: #(Int, fn(Int) -> Int, fn(Int) -> Int) = #(int, int_identity, int_identity_alias)\npub fn use_compound() { compound.1(compound.0) }\n" --- -module(my@mod). @@ -7,18 +8,22 @@ expression: "const int = 42\nconst int_alias = int\npub fn use_int_alias() { int -export([use_int_alias/0, use_int_identity_alias/0, use_compound/0]). +-file("/root/project/test/my/mod.gleam", 5). -spec int_identity(integer()) -> integer(). int_identity(I) -> I. +-file("/root/project/test/my/mod.gleam", 3). -spec use_int_alias() -> integer(). use_int_alias() -> 42. +-file("/root/project/test/my/mod.gleam", 7). -spec use_int_identity_alias() -> integer(). use_int_identity_alias() -> int_identity(42). +-file("/root/project/test/my/mod.gleam", 10). -spec use_compound() -> integer(). use_compound() -> (erlang:element(2, {42, fun int_identity/1, fun int_identity/1}))( diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_and_call.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_and_call.snap index 3aa1a52a8..e6fc5cc74 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_and_call.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_and_call.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/variables.rs +assertion_line: 34 expression: "\npub fn main(x) {\n fn(x) { x }(x)\n}\n" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn main(x) {\n fn(x) { x }(x)\n}\n" -export([main/1]). --spec main(I) -> I. +-file("/root/project/test/my/mod.gleam", 2). +-spec main(K) -> K. main(X) -> (fun(X@1) -> X@1 end)(X). diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_let.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_let.snap index 9801853b9..0e3d90325 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_let.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_let.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/variables.rs +assertion_line: 6 expression: "\npub fn go(a) {\n case a {\n 99 -> {\n let a = a\n 1\n }\n _ -> a\n }\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "\npub fn go(a) {\n case a {\n 99 -> {\n let a = a\n 1 -export([go/1]). +-file("/root/project/test/my/mod.gleam", 2). -spec go(integer()) -> integer(). go(A) -> case A of diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_param.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_param.snap index 8073bce20..da428383f 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_param.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_param.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/variables.rs +assertion_line: 23 expression: "pub fn main(board) {\nfn(board) { board }\n board\n}" --- -module(my@mod). @@ -7,6 +8,7 @@ expression: "pub fn main(board) {\nfn(board) { board }\n board\n}" -export([main/1]). +-file("/root/project/test/my/mod.gleam", 1). -spec main(I) -> I. main(Board) -> fun(Board@1) -> Board@1 end, diff --git a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_pipe.snap b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_pipe.snap index a08f0c4af..811193b9d 100644 --- a/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_pipe.snap +++ b/compiler-core/src/erlang/tests/snapshots/glistix_core__erlang__tests__variables__shadow_pipe.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/erlang/tests/variables.rs +assertion_line: 45 expression: "\npub fn main(x) {\n x\n |> fn(x) { x }\n}\n" --- -module(my@mod). @@ -7,7 +8,8 @@ expression: "\npub fn main(x) {\n x\n |> fn(x) { x }\n}\n" -export([main/1]). --spec main(L) -> L. +-file("/root/project/test/my/mod.gleam", 2). +-spec main(K) -> K. main(X) -> _pipe = X, (fun(X@1) -> X@1 end)(_pipe). diff --git a/compiler-core/src/error.rs b/compiler-core/src/error.rs index 5f4dcb0a1..d5a85d8fa 100644 --- a/compiler-core/src/error.rs +++ b/compiler-core/src/error.rs @@ -20,7 +20,7 @@ use pubgrub::report::DerivationTree; use pubgrub::version::Version; use std::collections::HashSet; use std::env; -use std::fmt::Debug; +use std::fmt::{Debug, Display}; use std::io::Write; use std::path::PathBuf; use termcolor::Buffer; @@ -259,7 +259,10 @@ file_names.iter().map(|x| x.as_str()).join(", "))] #[error("Opening docs at {path} failed: {error}")] FailedToOpenDocs { path: Utf8PathBuf, error: String }, - #[error("The package {package} requires a Gleam version satisfying {required_version} and you are using v{gleam_version}")] + #[error( + "The package {package} requires a Gleam version satisfying \ +{required_version} and you are using v{gleam_version}" + )] IncompatibleCompilerVersion { package: String, required_version: String, @@ -299,6 +302,40 @@ file_names.iter().map(|x| x.as_str()).join(", "))] #[error("Version already published")] HexPublishReplaceRequired { version: String }, + + #[error("The gleam version constraint is wrong and so cannot be published")] + CannotPublishWrongVersion { + minimum_required_version: SmallVersion, + wrongfully_allowed_version: SmallVersion, + }, +} + +/// This is to make clippy happy and not make the error variant too big by +/// storing an entire `hexpm::version::Version` in the error. +/// +/// This is enough to report wrong Gleam compiler versions. +/// +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct SmallVersion { + major: u8, + minor: u8, + patch: u8, +} + +impl Display for SmallVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&format!("{}.{}.{}", self.major, self.minor, self.patch)) + } +} + +impl SmallVersion { + pub fn from_hexpm(version: hexpm::version::Version) -> Self { + Self { + major: version.major as u8, + minor: version.minor as u8, + patch: version.patch as u8, + } + } } impl Error { @@ -369,10 +406,13 @@ impl Error { let mut conflicting_packages = HashSet::new(); collect_conflicting_packages(&derivation_tree, &mut conflicting_packages); - let report = format!("{}\n\n{}", - String::from("Unable to find compatible versions for the version constraints in your gleam.toml. The conflicting packages are:"), - conflicting_packages.into_iter().map(|s| format!("- {}", s)).join("\n")); - wrap(&report) + wrap_format!("Unable to find compatible versions for \ +the version constraints in your gleam.toml. \ +The conflicting packages are: + +{} +", + conflicting_packages.into_iter().map(|s| format!("- {}", s)).join("\n")) } ResolutionError::ErrorRetrievingDependencies { @@ -519,7 +559,7 @@ impl FileKind { } // https://github.com/rust-lang/rust/blob/03994e498df79aa1f97f7bbcfd52d57c8e865049/compiler/rustc_span/src/edit_distance.rs -fn edit_distance(a: &str, b: &str, limit: usize) -> Option { +pub fn edit_distance(a: &str, b: &str, limit: usize) -> Option { let mut a = &a.chars().collect::>()[..]; let mut b = &b.chars().collect::>()[..]; @@ -906,6 +946,24 @@ Please remove them and try again. location: None, }], + Error::CannotPublishWrongVersion { minimum_required_version, wrongfully_allowed_version } => vec![Diagnostic { + title: "Cannot publish package with wrong Gleam version range".into(), + text: wrap(&format!( + "Your package uses features that require at least v{minimum_required_version}. +But the Gleam version range specified in your `gleam.toml` would allow this \ +code to run on an earlier version like v{wrongfully_allowed_version}, \ +resulting in compilation errors!" + )), + level: Level::Error, + hint: Some(format!( + "Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = \">= {}\"", + minimum_required_version + )), + location: None, + }], + Error::CannotPublishLeakedInternalType { unfinished } => vec![Diagnostic { title: "Cannot publish unfinished code".into(), text: format!( @@ -1214,11 +1272,13 @@ Second: {second}" test_module, } => { let text = wrap_format!( - "The application module `{src_module}` is importing the test module `{test_module}`. + "The application module `{src_module}` \ +is importing the test module `{test_module}`. Test modules are not included in production builds so test \ -modules cannot import them. Perhaps move the `{test_module}` module to the src directory.", - ); +modules cannot import them. Perhaps move the `{test_module}` \ +module to the src directory.", + ); Diagnostic { title: "App importing test module".into(), @@ -1319,10 +1379,11 @@ not expect any. Please remove the label `{label}`." } TypeError::PositionalArgumentAfterLabelled { location } => { - let text = "This unlabeled argument has been supplied after a labelled argument. + let text = wrap("This unlabeled argument has been \ +supplied after a labelled argument. Once a labelled argument has been supplied all following arguments must -also be labelled." - .into(); +also be labelled."); + Diagnostic { title: "Unexpected positional argument".into(), text, @@ -1483,11 +1544,11 @@ Names in a Gleam module must be unique so one will need to be renamed." } TypeError::RecursiveType { location } => { - let text = "I don't know how to work out what type this value has. It seems -to be defined in terms of itself. + let text = wrap("I don't know how to work out what type this \ +value has. It seems to be defined in terms of itself. -Hint: Add some type annotations and try again." - .into(); +Hint: Add some type annotations and try again.") + ; Diagnostic { title: "Recursive type".into(), text, @@ -1505,11 +1566,11 @@ Hint: Add some type annotations and try again." } } - TypeError::NotFn { location, typ } => { + TypeError::NotFn { location, type_ } => { let mut printer = Printer::new(); let text = format!( "This value is being called as a function but its type is:\n\n{}", - printer.pretty_print(typ, 4) + printer.pretty_print(type_, 4) ); Diagnostic { title: "Type mismatch".into(), @@ -1531,7 +1592,7 @@ Hint: Add some type annotations and try again." TypeError::UnknownRecordField { usage, location, - typ, + type_, label, fields, variants, @@ -1541,7 +1602,7 @@ Hint: Add some type annotations and try again." // Give a hint about what type this value has. let mut text = format!( "The value being accessed has this type:\n\n{}\n", - printer.pretty_print(typ, 4) + printer.pretty_print(type_, 4) ); // Give a hint about what record fields this value has, if any. @@ -1743,9 +1804,8 @@ But function expects: given, .. } => { - let text = "Functions and constructors have to be called with their expected -number of arguments." - .into(); + let text = wrap("Functions and constructors have to be \ +called with their expected number of arguments."); let expected = match expected { 0 => "no arguments".into(), 1 => "1 argument".into(), @@ -1830,13 +1890,13 @@ assigned variables to all of them." } TypeError::UpdateMultiConstructorType { location } => { - let text = "This type has multiple constructors so it cannot be safely updated. -If this value was one of the other variants then the update would be -produce incorrect results. + let text = wrap("This type has multiple constructors \ +so it cannot be safely updated. If this value was one of the other variants \ +then the update would be produce incorrect results. -Consider pattern matching on it with a case expression and then +Consider pattern matching on it with a case expression and then\ constructing a new record with its values." - .into(); + ); Diagnostic { title: "Unsafe record update".into(), @@ -1871,8 +1931,9 @@ constructing a new record with its values." match hint { UnknownTypeHint::ValueInScopeWithSameName => { let hint = wrap_format!( - "There is a value in scope with the name `{name}`, but no type in scope with that name." - ); + "There is a value in scope with the name `{name}`, \ +but no type in scope with that name." + ); text.push('\n'); text.push_str(hint.as_str()); } @@ -1932,8 +1993,9 @@ constructing a new record with its values." // - is taken as an argument by this public function // - is taken as an argument by this public enum constructor // etc - let text = format!( - "The following type is private, but is being used by this public export. + let text = wrap_format!( + "The following type is private, but is \ +being used by this public export. {} @@ -1960,15 +2022,15 @@ Private types can only be used within the module that defines them.", TypeError::UnknownModule { location, name, - imported_modules, + suggestions } => Diagnostic { title: "Unknown module".into(), text: format!("No module has been found with the name `{name}`."), - hint: None, + hint: suggestions.first().map(|suggestion| suggestion.suggestion(name)), level: Level::Error, location: Some(Location { label: Label { - text: did_you_mean(name, imported_modules), + text: None, span: *location, }, path: path.clone(), @@ -2023,7 +2085,7 @@ Private types can only be used within the module that defines them.", format!("The module `{module_name}` does not have a `{name}` value.") }; Diagnostic { - title: "Unknown module field".into(), + title: "Unknown module value".into(), text, hint: None, level: Level::Error, @@ -2043,15 +2105,41 @@ Private types can only be used within the module that defines them.", } } + TypeError::ModuleAliasUsedAsName { + location, + name + } => { + let text = wrap( +"Modules are not values, so you cannot assign them to variables, pass \ +them to functions, or anything else that you would do with a value." + ); + Diagnostic { + title: format!("Module `{name}` used as a value"), + text, + hint: None, + level: Level::Error, + location: Some(Location { + label: Label { + text: None, + span: *location, + }, + path: path.clone(), + src: src.clone(), + extra_labels: vec![], + }), + } + } + TypeError::IncorrectNumClausePatterns { location, expected, given, } => { let text = wrap_format!( - "This case expression has {expected} subjects, but this pattern matches {given}. + "This case expression has {expected} subjects, \ +but this pattern matches {given}. Each clause must have a pattern for every subject value.", - ); + ); Diagnostic { title: "Incorrect number of patterns".into(), text, @@ -2072,7 +2160,8 @@ Each clause must have a pattern for every subject value.", TypeError::NonLocalClauseGuardVariable { location, name } => { let text = wrap_format!( "Variables used in guards must be either defined in the \ -function, or be an argument to the function. The variable `{name}` is not defined locally.", +function, or be an argument to the function. The variable \ +`{name}` is not defined locally.", ); Diagnostic { title: "Invalid guard variable".into(), @@ -2093,8 +2182,9 @@ function, or be an argument to the function. The variable `{name}` is not define TypeError::ExtraVarInAlternativePattern { location, name } => { let text = wrap_format!( -"All alternative patterns must define the same variables as the initial pattern. \ -This variable `{name}` has not been previously defined.", +"All alternative patterns must define the same variables as \ +the initial pattern. This variable `{name}` has not been \ +previously defined.", ); Diagnostic { title: "Extra alternative pattern variable".into(), @@ -2233,10 +2323,10 @@ tuple has {} elements so the highest valid index is {}.", } TypeError::NotATupleUnbound { location } => { - let text = "To index into a tuple we need to know it size, but we don't know -anything about this type yet. Please add some type annotations so -we can continue." - .into(); + let text = wrap("To index into a tuple we need to \ +know it size, but we don't know anything about this type yet. \ +Please add some type annotations so we can continue." + ); Diagnostic { title: "Type mismatch".into(), text, @@ -2255,10 +2345,10 @@ we can continue." } TypeError::RecordAccessUnknownType { location } => { - let text = "In order to access a record field we need to know what type it is, -but I can't tell the type here. Try adding type annotations to your -function and try again." - .into(); + let text = wrap("In order to access a record field \ +we need to know what type it is, but I can't tell \ +the type here. Try adding type annotations to your \ +function and try again."); Diagnostic { title: "Unknown type for record access".into(), text, @@ -2327,17 +2417,17 @@ function and try again." vec!["Hint: This option has no effect in BitArray values.".into()], ), - bit_array::ErrorType::SignednessUsedOnNonInt { typ } => ( + bit_array::ErrorType::SignednessUsedOnNonInt { type_ } => ( "Signedness is only valid with int types", - vec![format!("Hint: This segment has a type of {typ}")], + vec![format!("Hint: This segment has a type of {type_}")], ), - bit_array::ErrorType::TypeDoesNotAllowSize { typ } => ( + bit_array::ErrorType::TypeDoesNotAllowSize { type_ } => ( "Size cannot be specified here", - vec![format!("Hint: {typ} segments have an automatic size.")], + vec![format!("Hint: {type_} segments have an automatic size.")], ), - bit_array::ErrorType::TypeDoesNotAllowUnit { typ } => ( + bit_array::ErrorType::TypeDoesNotAllowUnit { type_ } => ( "Unit cannot be specified here", - vec![wrap(&format!("Hint: {typ} segments are sized based on their value \ + vec![wrap(&format!("Hint: {type_} segments are sized based on their value \ and cannot have a unit."))], ), bit_array::ErrorType::VariableUtfSegmentInPattern => ( @@ -2420,11 +2510,11 @@ Try a different name for this module." } TypeError::KeywordInModuleName { name, keyword } => { - let text = wrap(&format!( - "The module name `{name}` contains the keyword `{keyword}`, so importing \ -it would be a syntax error. + let text = wrap_format!( + "The module name `{name}` contains the keyword `{keyword}`, \ +so importing it would be a syntax error. Try a different name for this module." - )); + ); Diagnostic { title: "Invalid module name".into(), text, @@ -2691,13 +2781,12 @@ a valid Nix identifier." } TypeError::InexhaustiveLetAssignment { location, missing } => { - let mut text: String = - "This assignment uses a pattern that does not match all possible -values. If one of the other values is used then the assignment -will crash. + let mut text =wrap( + "This assignment uses a pattern that does not \ +match all possible values. If one of the other values \ +is used then the assignment will crash. -The missing patterns are:\n" - .into(); +The missing patterns are:\n"); for missing in missing { text.push_str("\n "); text.push_str(missing); @@ -2722,12 +2811,13 @@ The missing patterns are:\n" } TypeError::InexhaustiveCaseExpression { location, missing } => { - let mut text: String = - "This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. + let mut text =wrap( + "This case expression does not have a pattern \ +for all possible values. If it is run on one of the \ +values without a pattern then it will crash. The missing patterns are:\n" - .into(); + ); for missing in missing { text.push_str("\n "); text.push_str(missing); @@ -2855,16 +2945,16 @@ Rename or remove one of them.", } }, - TypeError::NotFnInUse { location, typ } => { + TypeError::NotFnInUse { location, type_ } => { let mut printer = Printer::new(); let text = wrap_format!( - "In a use expression, there should be a function on the right hand side \ -of `<-`, but this value has type: + "In a use expression, there should be a function on \ +the right hand side of `<-`, but this value has type: {} See: https://tour.gleam.run/advanced-features/use/", - printer.pretty_print(typ, 4) + printer.pretty_print(type_, 4) ); Diagnostic { @@ -2886,8 +2976,9 @@ See: https://tour.gleam.run/advanced-features/use/", TypeError::UseFnDoesntTakeCallback { location, actual_type: None } | TypeError::UseFnIncorrectArity { location, expected: 0, given: 1 } => { - let text = wrap("The function on the right of `<-` here takes no arguments. -But it has to take at least one argument, a callback function. + let text = wrap("The function on the right of `<-` here \ +takes no arguments, but it has to take at least \ +one argument, a callback function. See: https://tour.gleam.run/advanced-features/use/"); Diagnostic { @@ -2925,7 +3016,8 @@ here takes {expected_string}.\n"); if expected > given { if supplied_arguments == 0 { - text.push_str("The only argument that was supplied is the `use` callback function.\n") + text.push_str("The only argument that was supplied is \ +the `use` callback function.\n") } else { text.push_str(&format!("You supplied {supplied_arguments_string} \ and the final one is the `use` callback function.\n")); @@ -3028,16 +3120,20 @@ See: https://tour.gleam.run/advanced-features/use/"); let text = match kind { Named::Type | Named::TypeAlias | - Named::CustomTypeVariant => wrap_format!("Hint: {} names start with an uppercase letter and contain only lowercase letters, numbers, and uppercase letters. + Named::CustomTypeVariant => wrap_format!("Hint: {} names start with an uppercase \ +letter and contain only lowercase letters, numbers, \ +and uppercase letters. Try: {}", kind_str.to_title_case(), name.to_upper_camel_case()), Named::Variable | Named::TypeVariable | Named::Argument | Named::Label | Named::Constant | - Named::Function => wrap_format!("Hint: {} names start with a lowercase letter and contain a-z, 0-9, or _. + Named::Function => wrap_format!("Hint: {} names start with a lowercase letter \ +and contain a-z, 0-9, or _. Try: {}", kind_str.to_title_case(), name.to_snake_case()), - Named::Discard => wrap_format!("Hint: {} names start with _ and contain a-z, 0-9, or _. + Named::Discard => wrap_format!("Hint: {} names start with _ and contain \ +a-z, 0-9, or _. Try: _{}", kind_str.to_title_case(), name.to_snake_case()), }; @@ -3498,8 +3594,8 @@ issue in our tracker: https://github.com/gleam-lang/gleam/issues", gleam_version, } => { let text = format!( - "The package `{package}` requires a Gleam version satisfying {required_version} \ -but you are using v{gleam_version}.", + "The package `{package}` requires a Gleam version \ +satisfying {required_version} but you are using v{gleam_version}.", ); vec![Diagnostic { title: "Incompatible Gleam version".into(), diff --git a/compiler-core/src/exhaustiveness.rs b/compiler-core/src/exhaustiveness.rs index 3c2028e5f..b3c1ff6d9 100644 --- a/compiler-core/src/exhaustiveness.rs +++ b/compiler-core/src/exhaustiveness.rs @@ -32,6 +32,7 @@ mod missing_patterns; mod pattern; #[cfg(test)] mod pattern_tests; +pub mod printer; use self::pattern::{Constructor, Pattern, PatternId}; use crate::{ @@ -220,6 +221,7 @@ pub struct Diagnostics { pub struct Match { pub tree: Decision, pub diagnostics: Diagnostics, + pub subject_variables: Vec, } impl Match { @@ -239,6 +241,7 @@ pub struct Compiler<'a> { diagnostics: Diagnostics, patterns: Arena, environment: &'a Environment<'a>, + subject_variables: Vec, } impl<'a> Compiler<'a> { @@ -247,6 +250,7 @@ impl<'a> Compiler<'a> { environment, patterns, variable_id: 0, + subject_variables: Vec::new(), diagnostics: Diagnostics { missing: false, reachable: Vec::new(), @@ -254,10 +258,41 @@ impl<'a> Compiler<'a> { } } + pub fn subject_variable(&mut self, type_: Arc) -> Variable { + let variable = self.new_variable(type_); + self.subject_variables.push(variable.clone()); + variable + } + pub fn compile(mut self, rows: Vec) -> Match { + // If there are no rows, we get an immediate decision failure, + // which gives a pretty unhelpful error message. Instead, we + // run one pass of compiling to ensure we don't just suggest `_` + let tree = if rows.is_empty() { + // Even though we run a compile pass, an empty case expression is always + // invalid, so we make sure to report that here + self.diagnostics.missing = true; + let tree = self.compile_rows_for_variable( + self.subject_variables + .first() + .expect("Must have at least one subject") + .clone(), + Vec::new(), + ); + match tree { + // If there are no known constructors, we return failure since that + // better describes the state than an empty switch, and allows us to report + // `_` as the missing pattern. + Decision::Switch(_, cases, _) if cases.is_empty() => Decision::Failure, + _ => tree, + } + } else { + self.compile_rows(rows) + }; Match { - tree: self.compile_rows(rows), + tree, diagnostics: self.diagnostics, + subject_variables: self.subject_variables, } } @@ -313,7 +348,28 @@ impl<'a> Compiler<'a> { }; } - match self.branch_mode(&rows) { + // Get the most referred to variable across all rows + let mut counts = HashMap::new(); + for row in rows.iter() { + for col in &row.columns { + *counts.entry(col.variable.id).or_insert(0_usize) += 1 + } + } + + let variable = rows + .first() + .expect("Must have at least one row, otherwise we don't reach this point") + .columns + .iter() + .map(|col| col.variable.clone()) + .max_by_key(|var| counts.get(&var.id).copied().unwrap_or(0)) + .expect("The first row must have at least one column"); + + self.compile_rows_for_variable(variable, rows) + } + + fn compile_rows_for_variable(&mut self, variable: Variable, rows: Vec) -> Decision { + match self.branch_mode(variable) { BranchMode::Infinite { variable } => { let (cases, fallback) = self.compile_infinite_cases(rows, variable.clone()); Decision::Switch(variable, cases, Some(fallback)) @@ -693,31 +749,9 @@ impl<'a> Compiler<'a> { } } - /// Given a row, returns the kind of branch that is referred to the - /// most across all rows. - /// - /// # Panics - /// - /// Panics if there or no rows, or if the first row has no columns. - /// - fn branch_mode(&self, all_rows: &[Row]) -> BranchMode { - let mut counts = HashMap::new(); - - for row in all_rows { - for col in &row.columns { - *counts.entry(col.variable.id).or_insert(0_usize) += 1 - } - } - - let variable = all_rows - .first() - .expect("Must have at least one row") - .columns - .iter() - .map(|col| col.variable.clone()) - .max_by_key(|var| counts.get(&var.id).copied().unwrap_or(0)) - .expect("The first row must have at least one column"); - + /// Given a variable, returns the kind of branch associated with + /// that variable. + fn branch_mode(&self, variable: Variable) -> BranchMode { match collapse_links(variable.type_.clone()).as_ref() { Type::Fn { .. } | Type::Var { .. } => BranchMode::Infinite { variable }, @@ -762,7 +796,7 @@ impl<'a> Compiler<'a> { /// /// In a real compiler you'd have to ensure these variables don't conflict /// with other variables. - pub fn new_variable(&mut self, type_: Arc) -> Variable { + fn new_variable(&mut self, type_: Arc) -> Variable { let var = Variable { id: self.variable_id, type_, diff --git a/compiler-core/src/exhaustiveness/missing_patterns.rs b/compiler-core/src/exhaustiveness/missing_patterns.rs index 621201e86..f0f527539 100644 --- a/compiler-core/src/exhaustiveness/missing_patterns.rs +++ b/compiler-core/src/exhaustiveness/missing_patterns.rs @@ -1,7 +1,6 @@ -use super::{Constructor, Decision, Match, Variable}; +use super::{printer::Printer, Constructor, Decision, Match, Variable}; use crate::type_::environment::Environment; use ecow::EcoString; -use itertools::Itertools; use std::collections::{HashMap, HashSet}; /// Returns a list of patterns not covered by the match expression. @@ -9,7 +8,13 @@ pub fn missing_patterns(matches: &Match, environment: &Environment<'_>) -> Vec = names.into_iter().collect(); @@ -21,10 +26,15 @@ pub fn missing_patterns(matches: &Match, environment: &Environment<'_>) -> Vec, + }, + Tuple { + variable: Variable, arguments: Vec, }, Infinite { @@ -41,86 +51,20 @@ enum Term { } impl Term { - fn variable(&self) -> &Variable { + pub fn variable(&self) -> &Variable { match self { Term::Variant { variable, .. } => variable, + Term::Tuple { variable, .. } => variable, Term::Infinite { variable } => variable, Term::EmptyList { variable } => variable, Term::List { variable, .. } => variable, } } - - fn pattern_string(&self, terms: &[Term], mapping: &HashMap) -> EcoString { - match self { - Term::Variant { - name, arguments, .. - } => { - if arguments.is_empty() { - return name.clone(); - } - let args = arguments - .iter() - .map(|variable| { - mapping - .get(&variable.id) - .map(|&idx| { - terms - .get(idx) - .expect("Term must exist") - .pattern_string(terms, mapping) - }) - .unwrap_or_else(|| "_".into()) - }) - .join(", "); - format!("{}({})", name, args).into() - } - - Term::Infinite { .. } => "_".into(), - - Term::EmptyList { .. } => "[]".into(), - - Term::List { .. } => format!("[{}]", self.list_pattern_string(terms, mapping)).into(), - } - } - - fn list_pattern_string(&self, terms: &[Term], mapping: &HashMap) -> EcoString { - match self { - Term::Infinite { .. } | Term::Variant { .. } => "_".into(), - - Term::EmptyList { .. } => "".into(), - - Term::List { first, rest, .. } => { - let first = mapping - .get(&first.id) - .map(|&idx| { - terms - .get(idx) - .expect("Term must exist") - .pattern_string(terms, mapping) - }) - .unwrap_or_else(|| "_".into()); - let rest = mapping - .get(&rest.id) - .map(|&idx| { - terms - .get(idx) - .expect("Term must exist") - .list_pattern_string(terms, mapping) - }) - .unwrap_or_else(|| "_".into()); - - match rest.as_str() { - "" => first, - "_" => format!("{first}, ..").into(), - _ => format!("{first}, {rest}").into(), - } - } - } - } } fn add_missing_patterns( node: &Decision, + subjects: &Vec, terms: &mut Vec, missing: &mut HashSet, environment: &Environment<'_>, @@ -130,6 +74,7 @@ fn add_missing_patterns( Decision::Failure => { let mut mapping = HashMap::new(); + let printer = Printer::new(&environment.value_names); // At this point the terms stack looks something like this: // `[term, term + arguments, term, ...]`. To construct a pattern @@ -148,16 +93,13 @@ fn add_missing_patterns( _ = mapping.insert(step.variable().id, index); } - let name = terms - .first() - .map(|term| term.pattern_string(terms, &mapping)) - .unwrap_or_else(|| "_".into()); + let pattern = printer.print_terms(subjects, terms, &mapping); - _ = missing.insert(name); + _ = missing.insert(pattern); } Decision::Guard(_, _, fallback) => { - add_missing_patterns(fallback, terms, missing, environment); + add_missing_patterns(fallback, subjects, terms, missing, environment); } Decision::Switch(variable, cases, fallback) => { @@ -175,9 +117,8 @@ fn add_missing_patterns( Constructor::Tuple(_) => { let arguments = case.arguments.clone(); - terms.push(Term::Variant { + terms.push(Term::Tuple { variable: variable.clone(), - name: "#".into(), arguments, }); } @@ -196,17 +137,18 @@ fn add_missing_patterns( terms.push(Term::Variant { variable: variable.clone(), name, + module, arguments: case.arguments.clone(), }); } } - add_missing_patterns(&case.body, terms, missing, environment); + add_missing_patterns(&case.body, subjects, terms, missing, environment); _ = terms.pop(); } if let Some(node) = fallback { - add_missing_patterns(node, terms, missing, environment); + add_missing_patterns(node, subjects, terms, missing, environment); } } @@ -218,7 +160,7 @@ fn add_missing_patterns( terms.push(Term::EmptyList { variable: variable.clone(), }); - add_missing_patterns(empty, terms, missing, environment); + add_missing_patterns(empty, subjects, terms, missing, environment); _ = terms.pop(); terms.push(Term::List { @@ -226,7 +168,7 @@ fn add_missing_patterns( first: non_empty.first.clone(), rest: non_empty.rest.clone(), }); - add_missing_patterns(&non_empty.decision, terms, missing, environment); + add_missing_patterns(&non_empty.decision, subjects, terms, missing, environment); _ = terms.pop(); } } diff --git a/compiler-core/src/exhaustiveness/printer.rs b/compiler-core/src/exhaustiveness/printer.rs new file mode 100644 index 000000000..c4052582f --- /dev/null +++ b/compiler-core/src/exhaustiveness/printer.rs @@ -0,0 +1,546 @@ +use std::collections::HashMap; + +use ecow::EcoString; + +use super::{missing_patterns::Term, Variable}; + +#[derive(Debug, Default)] +pub struct ValueNames { + /// Mapping of imported modules to their locally used named + /// + /// key: The name of the module + /// value: The name the module is aliased to + /// + /// # Example 1 + /// + /// ```gleam + /// import mod1 as my_mod + /// ``` + /// would result in: + /// - key: "mod1" + /// - value: "my_mod" + /// + /// # Example 2 + /// + /// ```gleam + /// import mod1 + /// ``` + /// would result in: + /// - key: "mod1" + /// - value: "mod1" + /// + imported_modules: HashMap, + + /// Constructors which are imported in the current module in an + /// unqualified fashion. + /// + /// key: (Defining module name, type name) + /// value: Alias name + /// + /// # Example 1 + /// + /// ```gleam + /// import wibble.{Wobble} + /// ``` + /// would result in + /// - key: `("wibble", "Wobble")` + /// - value: `"Wobble"` + /// + /// # Example 2 + /// + /// ```gleam + /// import wibble.{Wobble as Woo} + /// ``` + /// would result in + /// - key: `("wibble", "Wobble")` + /// - value: `"Woo"` + /// + local_constructors: HashMap<(EcoString, EcoString), EcoString>, + + /// A map from local constructor names to the modules which they refer to. + /// This helps resolve cases like: + /// ```gleam + /// import wibble.{Wobble} + /// type Wibble { Wobble } + /// ``` + /// Here, `Wobble` is shadowed, causing `Wobble` not to be valid syntax + /// for `wibble.Wobble`. + /// + /// Each key is the local name of the constructor, and the value is the module + /// for which the unqualified version is valid. In the above example, + /// it would result in + /// - key: `"Wobble"` + /// - value: `"module"` (Whatever the current module is) + /// + /// But in this case: + /// ```gleam + /// import wibble.{Wobble as Wubble} + /// type Wibble { Wobble } + /// ``` + /// No shadowing occurs, so this isn't needed. + /// + constructor_names: HashMap, +} + +impl ValueNames { + pub fn new() -> Self { + Self { + local_constructors: Default::default(), + imported_modules: Default::default(), + constructor_names: Default::default(), + } + } + + /// Record a named value in this module. + pub fn named_constructor_in_scope( + &mut self, + module_name: EcoString, + value_name: EcoString, + local_alias: EcoString, + ) { + _ = self + .local_constructors + .insert((module_name.clone(), value_name), local_alias.clone()); + _ = self.constructor_names.insert(local_alias, module_name); + } + + /// Record an imported module in this module. + pub fn imported_module(&mut self, module_name: EcoString, module_alias: EcoString) { + _ = self.imported_modules.insert(module_name, module_alias) + } + + /// Get the name and optional module qualifier for a named constructor. + pub fn named_constructor<'a>( + &'a self, + module: &'a EcoString, + name: &'a EcoString, + ) -> NamedValueNames<'a> { + let key: (EcoString, EcoString) = (module.clone(), name.clone()); + + // There is a local name for this value, use that. + if let Some(name) = self.local_constructors.get(&key) { + // Only return unqualified syntax if the constructor is not shadowed, + // and unqualified syntax is valid. + if self + .constructor_names + .get(name) + .expect("Constructors must be added to both maps") + == module + { + return NamedValueNames::Unqualified(name.as_str()); + } + } + + // This value is from a module that has been imported + if let Some(module) = self.imported_modules.get(module) { + return NamedValueNames::Qualified(module, name.as_str()); + }; + + NamedValueNames::Unimported(name.as_str()) + } +} + +#[derive(Debug)] +pub enum NamedValueNames<'a> { + /// This value is from a module that has not been imported in this module. + Unimported(&'a str), + /// This value has been imported in an unqualified fashion in this module. + Unqualified(&'a str), + /// This value is from a module that has been imported. + Qualified(&'a str, &'a str), +} + +#[derive(Debug)] +pub struct Printer<'a> { + names: &'a ValueNames, +} + +impl<'a> Printer<'a> { + pub fn new(names: &'a ValueNames) -> Self { + Printer { names } + } + + pub fn print_terms( + &self, + subjects: &[Variable], + terms: &[Term], + mapping: &HashMap, + ) -> EcoString { + let mut buffer = EcoString::new(); + for (i, subject) in subjects.iter().enumerate() { + if i != 0 { + buffer.push_str(", "); + } + + match mapping.get(&subject.id) { + Some(&index) => { + let term = terms.get(index).expect("Term must exist"); + self.print(term, terms, mapping, &mut buffer); + } + None => buffer.push('_'), + } + } + buffer + } + + fn print( + &self, + term: &Term, + terms: &[Term], + mapping: &HashMap, + buffer: &mut EcoString, + ) { + match term { + Term::Variant { + name, + module, + arguments, + .. + } => { + let (module, name) = match self.names.named_constructor(module, name) { + NamedValueNames::Qualified(m, n) => (Some(m), n), + NamedValueNames::Unqualified(n) => (None, n), + NamedValueNames::Unimported(n) => { + (Some(module.split('/').last().unwrap_or(module)), n) + } + }; + + if let Some(module) = module { + buffer.push_str(module); + buffer.push('.'); + } + buffer.push_str(name); + + if arguments.is_empty() { + return; + } + buffer.push('('); + for (i, variable) in arguments.iter().enumerate() { + if i != 0 { + buffer.push_str(", "); + } + + if let Some(&idx) = mapping.get(&variable.id) { + self.print( + terms.get(idx).expect("Term must exist"), + terms, + mapping, + buffer, + ); + } else { + buffer.push('_'); + } + } + buffer.push(')'); + } + Term::Tuple { arguments, .. } => { + buffer.push_str("#("); + for (i, variable) in arguments.iter().enumerate() { + if i != 0 { + buffer.push_str(", "); + } + + if let Some(&idx) = mapping.get(&variable.id) { + self.print( + terms.get(idx).expect("Term must exist"), + terms, + mapping, + buffer, + ); + } else { + buffer.push('_'); + } + } + buffer.push(')'); + } + Term::Infinite { .. } => buffer.push('_'), + Term::EmptyList { .. } => buffer.push_str("[]"), + Term::List { .. } => { + buffer.push('['); + self.print_list(term, terms, mapping, buffer); + buffer.push(']'); + } + } + } + + fn print_list( + &self, + term: &Term, + terms: &[Term], + mapping: &HashMap, + buffer: &mut EcoString, + ) { + match term { + Term::Infinite { .. } | Term::Variant { .. } | Term::Tuple { .. } => buffer.push('_'), + + Term::EmptyList { .. } => {} + + Term::List { first, rest, .. } => { + if let Some(&idx) = mapping.get(&first.id) { + self.print( + terms.get(idx).expect("Term must exist"), + terms, + mapping, + buffer, + ) + } else { + buffer.push('_'); + } + + if let Some(&idx) = mapping.get(&rest.id) { + let term = terms.get(idx).expect("Term must exist"); + + match term { + Term::EmptyList { .. } => {} + _ => { + buffer.push_str(", "); + self.print_list(term, terms, mapping, buffer) + } + } + } else { + buffer.push_str(", .."); + } + } + } + } +} + +#[cfg(test)] +mod tests { + use super::{Printer, ValueNames}; + use std::{collections::HashMap, sync::Arc}; + + use crate::{ + exhaustiveness::{missing_patterns::Term, Variable}, + type_::Type, + }; + + /// Create a variable with a dummy type, for ease of writing tests + fn make_variable(id: usize) -> Variable { + Variable { + id, + type_: Arc::new(Type::Tuple { elems: Vec::new() }), + } + } + + fn get_mapping(terms: &[Term]) -> HashMap { + let mut mapping: HashMap = HashMap::new(); + + for (index, term) in terms.iter().enumerate() { + _ = mapping.insert(term.variable().id, index); + } + mapping + } + + #[test] + fn test_value_in_current_module() { + let mut names = ValueNames::new(); + + names.named_constructor_in_scope("module".into(), "Wibble".into(), "Wibble".into()); + + let printer = Printer::new(&names); + + let subjects = &[make_variable(0)]; + let term = Term::Variant { + variable: subjects[0].clone(), + name: "Wibble".into(), + module: "module".into(), + arguments: Vec::new(), + }; + + let terms = &[term]; + let mapping = get_mapping(terms); + + assert_eq!(printer.print_terms(subjects, terms, &mapping), "Wibble"); + } + + #[test] + fn test_value_in_current_module_with_arguments() { + let mut names = ValueNames::new(); + + names.named_constructor_in_scope("module".into(), "Wibble".into(), "Wibble".into()); + + let printer = Printer::new(&names); + + let var1 = make_variable(1); + + let var2 = make_variable(2); + + let subjects = &[make_variable(0)]; + let term = Term::Variant { + variable: subjects[0].clone(), + name: "Wibble".into(), + module: "module".into(), + arguments: vec![var1.clone(), var2.clone()], + }; + + let terms = &[ + term, + Term::EmptyList { variable: var1 }, + Term::Infinite { variable: var2 }, + ]; + let mapping = get_mapping(terms); + + assert_eq!( + printer.print_terms(subjects, terms, &mapping), + "Wibble([], _)" + ); + } + + #[test] + fn test_module_alias() { + let mut names = ValueNames::new(); + + names.imported_module("mod".into(), "shapes".into()); + + let printer = Printer::new(&names); + + let subjects = &[make_variable(0)]; + let term = Term::Variant { + variable: subjects[0].clone(), + name: "Rectangle".into(), + module: "mod".into(), + arguments: Vec::new(), + }; + + let terms = &[term]; + let mapping = get_mapping(terms); + + assert_eq!( + printer.print_terms(subjects, terms, &mapping), + "shapes.Rectangle" + ); + } + + #[test] + fn test_unqualified_value() { + let mut names = ValueNames::new(); + + names.named_constructor_in_scope("regex".into(), "Regex".into(), "Regex".into()); + + let printer = Printer::new(&names); + + let arg = make_variable(1); + + let subjects = &[make_variable(0)]; + let term = Term::Variant { + variable: subjects[0].clone(), + name: "Regex".into(), + module: "regex".into(), + arguments: vec![arg.clone()], + }; + + let terms = &[term, Term::Infinite { variable: arg }]; + let mapping = get_mapping(terms); + + assert_eq!(printer.print_terms(subjects, terms, &mapping), "Regex(_)"); + } + + #[test] + fn test_unqualified_value_with_alias() { + let mut names = ValueNames::new(); + + names.named_constructor_in_scope("regex".into(), "Regex".into(), "Reg".into()); + names.named_constructor_in_scope("gleam".into(), "None".into(), "None".into()); + + let printer = Printer::new(&names); + + let arg = make_variable(1); + + let subjects = &[make_variable(0)]; + let term = Term::Variant { + variable: subjects[0].clone(), + name: "Regex".into(), + module: "regex".into(), + arguments: vec![arg.clone()], + }; + + let terms = &[ + term, + Term::Variant { + variable: arg, + name: "None".into(), + module: "gleam".into(), + arguments: vec![], + }, + ]; + let mapping = get_mapping(terms); + + assert_eq!(printer.print_terms(subjects, terms, &mapping), "Reg(None)"); + } + + #[test] + fn test_list_pattern() { + let mut names = ValueNames::new(); + + names.named_constructor_in_scope("module".into(), "Type".into(), "Type".into()); + + let printer = Printer::new(&names); + + let var1 = make_variable(1); + let var2 = make_variable(2); + let var3 = make_variable(3); + + let subjects = &[make_variable(0)]; + let term = Term::List { + variable: subjects[0].clone(), + first: var1.clone(), + rest: var2.clone(), + }; + + let terms = &[ + term, + Term::Variant { + variable: var1, + name: "Type".into(), + module: "module".into(), + arguments: Vec::new(), + }, + Term::List { + variable: var2, + first: var3.clone(), + rest: make_variable(4), + }, + Term::Infinite { variable: var3 }, + ]; + let mapping = get_mapping(terms); + + assert_eq!( + printer.print_terms(subjects, terms, &mapping), + "[Type, _, ..]" + ); + } + + #[test] + fn test_multi_pattern() { + let mut names = ValueNames::new(); + + names.named_constructor_in_scope("gleam".into(), "Ok".into(), "Ok".into()); + names.named_constructor_in_scope("gleam".into(), "False".into(), "False".into()); + + let printer = Printer::new(&names); + + let subjects = &[make_variable(0), make_variable(1), make_variable(2)]; + + let terms = &[ + Term::Variant { + variable: subjects[0].clone(), + name: "Ok".into(), + module: "gleam".into(), + arguments: vec![make_variable(3)], + }, + Term::Variant { + variable: subjects[2].clone(), + name: "False".into(), + module: "gleam".into(), + arguments: Vec::new(), + }, + ]; + let mapping = get_mapping(terms); + + assert_eq!( + printer.print_terms(subjects, terms, &mapping), + "Ok(_), _, False" + ); + } +} diff --git a/compiler-core/src/format.rs b/compiler-core/src/format.rs index dc4655bc4..74023f6a5 100644 --- a/compiler-core/src/format.rs +++ b/compiler-core/src/format.rs @@ -10,6 +10,7 @@ use crate::{ docvec, io::Utf8Writer, parse::extra::{Comment, ModuleExtra}, + parse::SpannedString, pretty::{self, *}, type_::{self, Type}, warning::WarningEmitter, @@ -468,7 +469,7 @@ impl<'comments> Formatter<'comments> { Constant::Record { name, args, - module: Some(m), + module: Some((m, _)), .. } if args.is_empty() => m.to_doc().append(".").append(name.as_str()), @@ -488,7 +489,7 @@ impl<'comments> Formatter<'comments> { Constant::Record { name, args, - module: Some(m), + module: Some((m, _)), location, .. } => { @@ -506,7 +507,7 @@ impl<'comments> Formatter<'comments> { Constant::Var { name, - module: Some(module), + module: Some((module, _)), .. } => docvec![module, ".", name], @@ -648,14 +649,14 @@ impl<'comments> Formatter<'comments> { fn type_ast_constructor<'a>( &mut self, - module: &'a Option, + module: &'a Option<(EcoString, SrcSpan)>, name: &'a str, args: &'a [TypeAst], location: &SrcSpan, ) -> Document<'a> { let head = module .as_ref() - .map(|qualifier| qualifier.to_doc().append(".").append(name)) + .map(|(qualifier, _)| qualifier.to_doc().append(".").append(name)) .unwrap_or_else(|| name.to_doc()); if args.is_empty() { @@ -705,8 +706,8 @@ impl<'comments> Formatter<'comments> { &mut self, publicity: Publicity, name: &'a str, - args: &'a [(SrcSpan, EcoString)], - typ: &'a TypeAst, + args: &'a [SpannedString], + type_: &'a TypeAst, deprecation: &'a Deprecation, location: &SrcSpan, ) -> Document<'a> { @@ -724,7 +725,7 @@ impl<'comments> Formatter<'comments> { }; head.append(" =") - .append(line().append(self.type_ast(typ)).group().nest(INDENT)) + .append(line().append(self.type_ast(type_)).group().nest(INDENT)) } fn fn_arg<'a, A>(&mut self, arg: &'a Arg) -> Document<'a> { @@ -847,10 +848,17 @@ impl<'comments> Formatter<'comments> { if i != 0 && preceding_newline { documents.push(lines(2)); } else if i != 0 { - documents.push(lines(1)); + documents.push(line()); } previous_position = statement.location().end; documents.push(self.statement(statement).group()); + + // If the last statement is a use we make sure it's followed by a + // todo to make it explicit it has an unimplemented callback. + if statement.is_use() && i == count - 1 { + documents.push(line()); + documents.push("todo".to_doc()); + } } if count == 1 && statements.first().is_expression() { documents.to_doc() @@ -1108,7 +1116,7 @@ impl<'comments> Formatter<'comments> { &mut self, name: &'a str, args: &'a [CallArg], - module: &'a Option, + module: &'a Option<(EcoString, SrcSpan)>, spread: Option, location: &SrcSpan, ) -> Document<'a> { @@ -1123,7 +1131,7 @@ impl<'comments> Formatter<'comments> { } let name = match module { - Some(m) => m.to_doc().append(".").append(name), + Some((m, _)) => m.to_doc().append(".").append(name), None => name.to_doc(), }; @@ -1642,7 +1650,7 @@ impl<'comments> Formatter<'comments> { &mut self, publicity: Publicity, name: &'a str, - args: &'a [(SrcSpan, EcoString)], + args: &'a [SpannedString], location: &'a SrcSpan, ) -> Document<'a> { let _ = self.pop_empty_lines(location.start); @@ -1773,7 +1781,23 @@ impl<'comments> Formatter<'comments> { fn tuple_index<'a>(&mut self, tuple: &'a UntypedExpr, index: u64) -> Document<'a> { match tuple { - UntypedExpr::TupleIndex { .. } => self.expr(tuple).surround("{", "}"), + // In case we have a block with a single variable tuple access we + // remove that redundat wrapper: + // + // {tuple.1}.0 becomes + // tuple.1.0 + // + UntypedExpr::Block { statements, .. } => match statements.as_slice() { + [Statement::Expression(tuple @ UntypedExpr::TupleIndex { tuple: inner, .. })] + // We can't apply this change if the inner thing is a + // literal tuple because the compiler cannot currently parse + // it: `#(1, #(2, 3)).1.0` is a syntax error at the moment. + if !inner.is_tuple() => + { + self.expr(tuple) + } + _ => self.expr(tuple), + }, _ => self.expr(tuple), } .append(".") @@ -1868,7 +1892,7 @@ impl<'comments> Formatter<'comments> { } else if space_before { lines(2).append(clause_doc) } else { - lines(1).append(clause_doc) + line().append(clause_doc) } } @@ -2125,8 +2149,8 @@ impl<'comments> Formatter<'comments> { fn list_pattern<'a>( &mut self, - elements: &'a [Pattern<()>], - tail: &'a Option>>, + elements: &'a [UntypedPattern], + tail: &'a Option>, ) -> Document<'a> { if elements.is_empty() { return match tail { @@ -2649,7 +2673,7 @@ impl<'a> Documentable<'a> for &'a ArgNames { fn pub_(publicity: Publicity) -> Document<'static> { match publicity { - Publicity::Public | Publicity::Internal => "pub ".to_doc(), + Publicity::Public | Publicity::Internal { .. } => "pub ".to_doc(), Publicity::Private => nil(), } } @@ -2963,9 +2987,9 @@ fn constant_call_arg_formatting( } struct AttributesPrinter<'a> { - external_erlang: &'a Option<(EcoString, EcoString)>, - external_javascript: &'a Option<(EcoString, EcoString)>, - external_nix: &'a Option<(EcoString, EcoString)>, + external_erlang: &'a Option<(EcoString, EcoString, SrcSpan)>, + external_javascript: &'a Option<(EcoString, EcoString, SrcSpan)>, + external_nix: &'a Option<(EcoString, EcoString, SrcSpan)>, deprecation: &'a Deprecation, internal: bool, } @@ -2981,17 +3005,26 @@ impl<'a> AttributesPrinter<'a> { } } - pub fn set_external_erlang(mut self, external: &'a Option<(EcoString, EcoString)>) -> Self { + pub fn set_external_erlang( + mut self, + external: &'a Option<(EcoString, EcoString, SrcSpan)>, + ) -> Self { self.external_erlang = external; self } - pub fn set_external_javascript(mut self, external: &'a Option<(EcoString, EcoString)>) -> Self { + pub fn set_external_javascript( + mut self, + external: &'a Option<(EcoString, EcoString, SrcSpan)>, + ) -> Self { self.external_javascript = external; self } - pub fn set_external_nix(mut self, external: &'a Option<(EcoString, EcoString)>) -> Self { + pub fn set_external_nix( + mut self, + external: &'a Option<(EcoString, EcoString, SrcSpan)>, + ) -> Self { self.external_nix = external; self } @@ -3017,15 +3050,15 @@ impl<'a> Documentable<'a> for AttributesPrinter<'a> { }; // @external attributes - if let Some((m, f)) = self.external_erlang { + if let Some((m, f, _)) = self.external_erlang { attributes.push(docvec!["@external(erlang, \"", m, "\", \"", f, "\")"]) }; - if let Some((m, f)) = self.external_javascript { + if let Some((m, f, _)) = self.external_javascript { attributes.push(docvec!["@external(javascript, \"", m, "\", \"", f, "\")"]) }; - if let Some((m, f)) = self.external_nix { + if let Some((m, f, _)) = self.external_nix { attributes.push(docvec!["@external(nix, \"", m, "\", \"", f, "\")"]) }; diff --git a/compiler-core/src/format/tests.rs b/compiler-core/src/format/tests.rs index d1db40049..e5152d044 100644 --- a/compiler-core/src/format/tests.rs +++ b/compiler-core/src/format/tests.rs @@ -3166,7 +3166,7 @@ fn tuple_access2() { fn tuple_access3() { assert_format!( r#"fn main() { - { tup.1 }.2 + tup.1.2 } "# ); diff --git a/compiler-core/src/format/tests/tuple.rs b/compiler-core/src/format/tests/tuple.rs index 0ff9a457d..44ffe09a8 100644 --- a/compiler-core/src/format/tests/tuple.rs +++ b/compiler-core/src/format/tests/tuple.rs @@ -1,4 +1,4 @@ -use crate::assert_format; +use crate::{assert_format, assert_format_rewrite}; // https://github.com/gleam-lang/gleam/issues/2083 #[test] @@ -67,3 +67,37 @@ pub fn main() { "# ); } + +#[test] +fn nested_tuple_access() { + assert_format!( + r#"pub fn main() { + wibble.1.0 +} +"# + ); +} + +#[test] +fn nested_tuple_with_needless_block() { + assert_format_rewrite!( + r#"pub fn main() { + { wibble.1 }.0 +} +"#, + r#"pub fn main() { + wibble.1.0 +} +"# + ); +} + +#[test] +fn nested_literal_tuple_with_needless_block_is_not_changed() { + assert_format!( + r#"pub fn main() { + { #(wibble, wobble).1 }.0 +} +"# + ); +} diff --git a/compiler-core/src/format/tests/use_.rs b/compiler-core/src/format/tests/use_.rs index e62849a0a..47dc42ede 100644 --- a/compiler-core/src/format/tests/use_.rs +++ b/compiler-core/src/format/tests/use_.rs @@ -1,10 +1,11 @@ -use crate::assert_format; +use crate::{assert_format, assert_format_rewrite}; #[test] fn use_1() { assert_format!( r#"pub fn main() { use <- benchmark("thingy") + todo } "# ); @@ -15,6 +16,7 @@ fn use_2() { assert_format!( r#"pub fn main() { use user <- login() + todo } "# ); @@ -25,6 +27,7 @@ fn use_3() { assert_format!( r#"pub fn main() { use one, two, three, four <- get_multiple_things() + todo } "# ); @@ -49,6 +52,7 @@ fn use_4() { twelve, thirteen <- get_multiple_things_with_a_longer_function + todo } "# ); @@ -73,6 +77,7 @@ fn use_5() { twelve, thirteen <- get_multiple_things_with_a_longer_function(a, b, c, d) + todo } "# ); @@ -106,6 +111,7 @@ fn use_6() { "seven", "eight", ) + todo } "# ); @@ -130,6 +136,7 @@ fn use_pipe_everything() { r#"pub fn main() { { use <- a + todo } |> b c @@ -152,6 +159,7 @@ fn long_right_hand_side_0_arguments() { "seven", "eight", ) + todo } "# ); @@ -171,6 +179,7 @@ fn long_right_hand_side_1_argument() { "seven", "eight", ) + todo } "# ); @@ -190,6 +199,7 @@ fn long_right_hand_side_2_arguments() { "seven", "eight", ) + todo } "# ); @@ -203,6 +213,7 @@ fn arity_1_var_call() { file.read() |> promise.map(something), ) + todo } "# ); @@ -216,6 +227,7 @@ fn arity_1_access_call() { file.read() |> promise.map(something), ) + todo } "# ); @@ -322,6 +334,23 @@ fn comment() { r#"fn main() { // comment use x <- result.then(y) + todo +} +"# + ); +} + +// https://github.com/gleam-lang/gleam/issues/3605 +#[test] +fn use_with_empty_callback_body_is_rewritten_to_have_a_todo() { + assert_format_rewrite!( + r#"fn main() { + use wibble, wobble <- woo +} +"#, + r#"fn main() { + use wibble, wobble <- woo + todo } "# ); diff --git a/compiler-core/src/javascript.rs b/compiler-core/src/javascript.rs index 889ba148a..16bbff9cf 100644 --- a/compiler-core/src/javascript.rs +++ b/compiler-core/src/javascript.rs @@ -353,7 +353,7 @@ impl<'a> Generator<'a> { Definition::Function(Function { name: Some((_, name)), publicity, - external_javascript: Some((module, function)), + external_javascript: Some((module, function, _location)), .. }) => { self.register_external_function( diff --git a/compiler-core/src/javascript/expression.rs b/compiler-core/src/javascript/expression.rs index 258450e2e..245922c33 100644 --- a/compiler-core/src/javascript/expression.rs +++ b/compiler-core/src/javascript/expression.rs @@ -326,7 +326,7 @@ impl<'module> Generator<'module> { let size_int = match *size.clone() { TypedExpr::Int { location: _, - typ: _, + type_: _, value, } => value.parse().unwrap_or(0), _ => 0, @@ -456,7 +456,9 @@ impl<'module> Generator<'module> { constant_expression(Context::Function, self.tracker, literal) } ValueConstructorVariant::Record { arity, .. } => { - Ok(self.record_constructor(constructor.type_.clone(), None, name, *arity)) + let type_ = constructor.type_.clone(); + let tracker = &mut self.tracker; + Ok(record_constructor(type_, None, name, *arity, tracker)) } ValueConstructorVariant::ModuleFn { .. } | ValueConstructorVariant::ModuleConstant { .. } @@ -464,48 +466,6 @@ impl<'module> Generator<'module> { } } - fn record_constructor<'a>( - &mut self, - type_: Arc, - qualifier: Option<&'a str>, - name: &'a str, - arity: u16, - ) -> Document<'a> { - if qualifier.is_none() && type_.is_result_constructor() { - if name == "Ok" { - self.tracker.ok_used = true; - } else if name == "Error" { - self.tracker.error_used = true; - } - } - if type_.is_bool() && name == "True" { - "true".to_doc() - } else if type_.is_bool() { - "false".to_doc() - } else if type_.is_nil() { - "undefined".to_doc() - } else if arity == 0 { - match qualifier { - Some(module) => docvec!["new $", module, ".", name, "()"], - None => docvec!["new ", name, "()"], - } - } else { - let vars = (0..arity).map(|i| Document::String(format!("var{i}"))); - let body = docvec![ - "return ", - construct_record(qualifier, name, vars.clone()), - ";" - ]; - docvec!( - docvec!(wrap_args(vars), " => {", break_("", " "), body) - .nest(INDENT) - .append(break_("", " ")) - .group(), - "}", - ) - } - } - fn pipeline<'a>( &mut self, assignments: &'a [TypedAssignment], @@ -741,8 +701,8 @@ impl<'module> Generator<'module> { fn assignment_no_match<'a>(&mut self, location: SrcSpan, subject: Document<'a>) -> Output<'a> { Ok(self.throw_error( - "assignment_no_match", - &string("Assignment pattern did not match"), + "let_assert", + &string("Pattern match failed, no pattern matched the value."), location, [("value", subject)], )) @@ -755,19 +715,11 @@ impl<'module> Generator<'module> { } fn call<'a>(&mut self, fun: &'a TypedExpr, arguments: &'a [CallArg]) -> Output<'a> { - let scope_position = self.scope_position; - let function_position = self.function_position; - - self.scope_position = Position::NotTail; - self.function_position = Position::NotTail; let arguments = arguments .iter() - .map(|element| self.wrap_expression(&element.value)) + .map(|element| self.not_in_tail_position(|gen| gen.wrap_expression(&element.value))) .try_collect()?; - self.function_position = function_position; - self.scope_position = scope_position; - self.call_with_doc_args(fun, arguments) } @@ -1026,36 +978,22 @@ impl<'module> Generator<'module> { } fn todo<'a>(&mut self, message: Option<&'a TypedExpr>, location: &'a SrcSpan) -> Output<'a> { - let scope_position = self.scope_position; - self.scope_position = Position::NotTail; - let message = match message { - Some(m) => self.expression(m)?, - None => string("This has not yet been implemented"), + Some(m) => self.not_in_tail_position(|gen| gen.expression(m))?, + None => string("`todo` expression evaluated. This code has not yet been implemented."), }; let doc = self.throw_error("todo", &message, *location, vec![]); - // Reset tail position so later values are returned as needed. i.e. - // following clauses in a case expression. - self.scope_position = scope_position; - Ok(doc) } fn panic<'a>(&mut self, location: &'a SrcSpan, message: Option<&'a TypedExpr>) -> Output<'a> { - let scope_position = self.scope_position; - self.scope_position = Position::NotTail; - let message = match message { - Some(m) => self.expression(m)?, - None => string("panic expression evaluated"), + Some(m) => self.not_in_tail_position(|gen| gen.expression(m))?, + None => string("`panic` expression evaluated."), }; let doc = self.throw_error("panic", &message, *location, vec![]); - // Reset tail position so later values are returned as needed. i.e. - // following clauses in a case expression. - self.scope_position = scope_position; - Ok(doc) } @@ -1106,7 +1044,7 @@ impl<'module> Generator<'module> { ModuleValueConstructor::Record { name, arity, type_, .. - } => self.record_constructor(type_.clone(), Some(module), name, *arity), + } => record_constructor(type_.clone(), Some(module), name, *arity, self.tracker), } } @@ -1278,23 +1216,23 @@ pub(crate) fn guard_constant_expression<'a>( .map(|e| guard_constant_expression(assignments, tracker, e)), ) } - Constant::Record { typ, name, .. } if typ.is_bool() && name == "True" => { + Constant::Record { type_, name, .. } if type_.is_bool() && name == "True" => { Ok("true".to_doc()) } - Constant::Record { typ, name, .. } if typ.is_bool() && name == "False" => { + Constant::Record { type_, name, .. } if type_.is_bool() && name == "False" => { Ok("false".to_doc()) } - Constant::Record { typ, .. } if typ.is_nil() => Ok("undefined".to_doc()), + Constant::Record { type_, .. } if type_.is_nil() => Ok("undefined".to_doc()), Constant::Record { args, module, name, tag, - typ, + type_, .. } => { - if typ.is_result() { + if type_.is_result() { if tag == "Ok" { tracker.ok_used = true; } else { @@ -1305,7 +1243,11 @@ pub(crate) fn guard_constant_expression<'a>( .iter() .map(|arg| guard_constant_expression(assignments, tracker, &arg.value)) .try_collect()?; - Ok(construct_record(module.as_deref(), name, field_values)) + Ok(construct_record( + module.as_ref().map(|(module, _)| module.as_str()), + name, + field_values, + )) } Constant::BitArray { segments, .. } => bit_array(tracker, segments, |tracker, constant| { @@ -1363,35 +1305,56 @@ pub(crate) fn constant_expression<'a>( } } - Constant::Record { typ, name, .. } if typ.is_bool() && name == "True" => { + Constant::Record { type_, name, .. } if type_.is_bool() && name == "True" => { Ok("true".to_doc()) } - Constant::Record { typ, name, .. } if typ.is_bool() && name == "False" => { + Constant::Record { type_, name, .. } if type_.is_bool() && name == "False" => { Ok("false".to_doc()) } - Constant::Record { typ, .. } if typ.is_nil() => Ok("undefined".to_doc()), + Constant::Record { type_, .. } if type_.is_nil() => Ok("undefined".to_doc()), Constant::Record { args, module, name, tag, - typ, + type_, .. } => { - if typ.is_result() { + if type_.is_result() { if tag == "Ok" { tracker.ok_used = true; } else { tracker.error_used = true; } } + + // If there's no arguments and the type is a function that takes + // arguments then this is the constructor being referenced, not the + // function being called. + if let Some(arity) = type_.fn_arity() { + if args.is_empty() && arity != 0 { + let arity = arity as u16; + return Ok(record_constructor( + type_.clone(), + None, + name, + arity, + tracker, + )); + } + } + let field_values: Vec<_> = args .iter() .map(|arg| constant_expression(context, tracker, &arg.value)) .try_collect()?; - let constructor = construct_record(module.as_deref(), name, field_values); + let constructor = construct_record( + module.as_ref().map(|(module, _)| module.as_str()), + name, + field_values, + ); match context { Context::Constant => Ok(docvec!["/* @__PURE__ */ ", constructor]), Context::Function => Ok(constructor), @@ -1411,7 +1374,7 @@ pub(crate) fn constant_expression<'a>( Constant::Var { name, module, .. } => Ok({ match module { None => maybe_escape_identifier_doc(name), - Some(module) => { + Some((module, _)) => { // JS keywords can be accessed here, but we must escape anyway // as we escape when exporting such names in the first place, // and the imported name has to match the exported name. @@ -1432,7 +1395,7 @@ pub(crate) fn constant_expression<'a>( fn bit_array<'a>( tracker: &mut UsageTracker, - segments: &'a [BitArraySegment>], + segments: &'a [TypedConstantBitArraySegment], mut constant_expr_fun: impl FnMut(&mut UsageTracker, &'a TypedConstant) -> Output<'a>, ) -> Output<'a> { tracker.bit_array_literal_used = true; @@ -1510,7 +1473,7 @@ struct SizedBitArraySegmentDetails<'a> { } fn sized_bit_array_segment_details<'a>( - segment: &'a BitArraySegment>, + segment: &'a TypedConstantBitArraySegment, tracker: &mut UsageTracker, constant_expr_fun: &mut impl FnMut(&mut UsageTracker, &'a TypedConstant) -> Output<'a>, ) -> Result, Error> { @@ -1768,3 +1731,45 @@ fn immediately_involked_function_expression_document(document: Document<'_>) -> ) .group() } + +fn record_constructor<'a>( + type_: Arc, + qualifier: Option<&'a str>, + name: &'a str, + arity: u16, + tracker: &mut UsageTracker, +) -> Document<'a> { + if qualifier.is_none() && type_.is_result_constructor() { + if name == "Ok" { + tracker.ok_used = true; + } else if name == "Error" { + tracker.error_used = true; + } + } + if type_.is_bool() && name == "True" { + "true".to_doc() + } else if type_.is_bool() { + "false".to_doc() + } else if type_.is_nil() { + "undefined".to_doc() + } else if arity == 0 { + match qualifier { + Some(module) => docvec!["new $", module, ".", name, "()"], + None => docvec!["new ", name, "()"], + } + } else { + let vars = (0..arity).map(|i| Document::String(format!("var{i}"))); + let body = docvec![ + "return ", + construct_record(qualifier, name, vars.clone()), + ";" + ]; + docvec!( + docvec!(wrap_args(vars), " => {", break_("", " "), body) + .nest(INDENT) + .append(break_("", " ")) + .group(), + "}", + ) + } +} diff --git a/compiler-core/src/javascript/pattern.rs b/compiler-core/src/javascript/pattern.rs index c9ee67c28..79357ad0d 100644 --- a/compiler-core/src/javascript/pattern.rs +++ b/compiler-core/src/javascript/pattern.rs @@ -1,11 +1,11 @@ -use std::sync::{Arc, OnceLock}; +use std::sync::OnceLock; use super::{expression::is_js_scalar, *}; use crate::{ analyse::Inferred, javascript::endianness::Endianness, strings::convert_string_escape_chars, - type_::{FieldMap, PatternConstructor, Type}, + type_::{FieldMap, PatternConstructor}, }; pub static ASSIGNMENT_VAR: &str = "$"; @@ -536,7 +536,9 @@ impl<'module_ctx, 'expression_gen, 'a> Generator<'module_ctx, 'expression_gen, ' _ if type_.is_result() => { self.push_result_check(subject.clone(), record_name == "Ok") } - Some(m) => self.push_variant_check(subject.clone(), docvec!["$", m, ".", name]), + Some((m, _)) => { + self.push_variant_check(subject.clone(), docvec!["$", m, ".", name]) + } None => self.push_variant_check(subject.clone(), name.to_doc()), } @@ -669,7 +671,7 @@ impl<'module_ctx, 'expression_gen, 'a> Generator<'module_ctx, 'expression_gen, ' } fn sized_bit_array_segment_details( - segment: &BitArraySegment>, Arc>, + segment: &TypedPatternBitArraySegment, ) -> Result { use BitArrayOption as Opt; @@ -704,7 +706,7 @@ impl<'module_ctx, 'expression_gen, 'a> Generator<'module_ctx, 'expression_gen, ' .parse::() .expect("part of an Int node should always parse as integer")), _ => Err(Error::Unsupported { - feature: "This bit array size option in patterns".into(), + feature: "Non-constant size option in patterns".into(), location: segment.location, }), }, @@ -721,9 +723,17 @@ impl<'module_ctx, 'expression_gen, 'a> Generator<'module_ctx, 'expression_gen, ' }?; // 16-bit floats are not supported - if segment.type_ == crate::type_::float() && size == 16usize { + if segment.type_ == crate::type_::float() && size == 16 { + return Err(Error::Unsupported { + feature: "Float width of 16 bits in patterns".into(), + location: segment.location, + }); + } + + // Ints that aren't byte-aligned are not supported + if segment.type_ == crate::type_::int() && size % 8 != 0 { return Err(Error::Unsupported { - feature: "This bit array size option in patterns".into(), + feature: "Non byte aligned integer in patterns".into(), location: segment.location, }); } @@ -826,7 +836,7 @@ pub struct CompiledPattern<'a> { pub assignments: Vec>, } -impl<'a> CompiledPattern<'a> { +impl CompiledPattern<'_> { pub fn has_assignments(&self) -> bool { !self.assignments.is_empty() } diff --git a/compiler-core/src/javascript/tests.rs b/compiler-core/src/javascript/tests.rs index 1474a3e95..6596d1cb8 100644 --- a/compiler-core/src/javascript/tests.rs +++ b/compiler-core/src/javascript/tests.rs @@ -39,7 +39,7 @@ pub static CURRENT_PACKAGE: &str = "thepackage"; macro_rules! assert_js_with_multiple_imports { ($(($name:literal, $module_src:literal)),+; $src:literal) => { let output = - $crate::javascript::tests::compile_js($src, vec![$((CURRENT_PACKAGE, $name, $module_src)),*]); + $crate::javascript::tests::compile_js($src, vec![$((CURRENT_PACKAGE, $name, $module_src)),*]).expect("compilation failed"); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }; } @@ -48,37 +48,51 @@ macro_rules! assert_js_with_multiple_imports { macro_rules! assert_js { (($dep_package:expr, $dep_name:expr, $dep_src:expr), $src:expr $(,)?) => {{ let output = - $crate::javascript::tests::compile_js($src, vec![($dep_package, $dep_name, $dep_src)]); + $crate::javascript::tests::compile_js($src, vec![($dep_package, $dep_name, $dep_src)]) + .expect("compilation failed"); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }}; (($dep_package:expr, $dep_name:expr, $dep_src:expr), $src:expr, $js:expr $(,)?) => {{ let output = - $crate::javascript::tests::compile_js($src, Some(($dep_package, $dep_name, $dep_src))); + $crate::javascript::tests::compile_js($src, Some(($dep_package, $dep_name, $dep_src))) + .expect("compilation failed"); assert_eq!(($src, output), ($src, $js.to_string())); }}; ($src:expr $(,)?) => {{ - let output = $crate::javascript::tests::compile_js($src, vec![]); + let output = + $crate::javascript::tests::compile_js($src, vec![]).expect("compilation failed"); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }}; ($src:expr, $js:expr $(,)?) => {{ - let output = $crate::javascript::tests::compile_js($src, vec![]); + let output = + $crate::javascript::tests::compile_js($src, vec![]).expect("compilation failed"); assert_eq!(($src, output), ($src, $js.to_string())); }}; } +#[macro_export] +macro_rules! assert_js_error { + ($src:expr $(,)?) => {{ + let output = $crate::javascript::tests::expect_js_error($src, vec![]); + insta::assert_snapshot!(insta::internals::AutoName, output, $src); + }}; +} + #[macro_export] macro_rules! assert_ts_def { (($dep_package:expr, $dep_name:expr, $dep_src:expr), $src:expr $(,)?) => {{ let output = - $crate::javascript::tests::compile_ts($src, vec![($dep_package, $dep_name, $dep_src)]); + $crate::javascript::tests::compile_ts($src, vec![($dep_package, $dep_name, $dep_src)]) + .expect("compilation failed"); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }}; ($src:expr $(,)?) => {{ - let output = $crate::javascript::tests::compile_ts($src, vec![]); + let output = + $crate::javascript::tests::compile_ts($src, vec![]).expect("compilation failed"); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }}; } @@ -148,7 +162,7 @@ pub fn compile(src: &str, deps: Vec<(&str, &str, &str)>) -> TypedModule { .expect("should successfully infer") } -pub fn compile_js(src: &str, deps: Vec<(&str, &str, &str)>) -> String { +pub fn compile_js(src: &str, deps: Vec<(&str, &str, &str)>) -> Result { let ast = compile(src, deps); let line_numbers = LineNumbers::new(src); module( @@ -156,13 +170,28 @@ pub fn compile_js(src: &str, deps: Vec<(&str, &str, &str)>) -> String { &line_numbers, Utf8Path::new(""), &"".into(), - TargetSupport::NotEnforced, + TargetSupport::Enforced, TypeScriptDeclarations::None, ) - .unwrap() } -pub fn compile_ts(src: &str, deps: Vec<(&str, &str, &str)>) -> String { +pub fn compile_ts(src: &str, deps: Vec<(&str, &str, &str)>) -> Result { let ast = compile(src, deps); - ts_declaration(&ast, Utf8Path::new(""), &src.into()).unwrap() + ts_declaration(&ast, Utf8Path::new(""), &src.into()) +} + +pub fn expect_js_error(src: &str, deps: Vec<(&str, &str, &str)>) -> String { + let error = compile_js(src, deps).expect_err("should not compile"); + println!("er: {:#?}", error); + let better_error = match error { + crate::Error::JavaScript { + error: inner_error, .. + } => crate::Error::JavaScript { + src: src.into(), + path: Utf8PathBuf::from("/src/javascript/error.gleam"), + error: inner_error, + }, + _ => panic!("expected js error, got {:#?}", error), + }; + better_error.pretty_string() } diff --git a/compiler-core/src/javascript/tests/bit_arrays.rs b/compiler-core/src/javascript/tests/bit_arrays.rs index 66abfaf6c..47966e40b 100644 --- a/compiler-core/src/javascript/tests/bit_arrays.rs +++ b/compiler-core/src/javascript/tests/bit_arrays.rs @@ -1,4 +1,4 @@ -use crate::{assert_js, assert_ts_def}; +use crate::{assert_js, assert_js_error, assert_ts_def}; #[test] fn empty() { @@ -385,6 +385,29 @@ fn go(x) { ); } +#[test] +fn match_dynamic_size_error() { + assert_js_error!( + r#" +fn go(x) { + let n = 16 + let assert <> = x +} +"# + ); +} + +#[test] +fn match_non_byte_aligned_size_error() { + assert_js_error!( + r#" +fn go(x) { + let assert <> = x +} +"# + ); +} + #[test] fn discard_sized() { assert_js!( @@ -474,6 +497,17 @@ fn go(x) { ); } +#[test] +fn match_float_16_bit_error() { + assert_js_error!( + r#" +fn go(x) { + let assert <> = x +} +"# + ); +} + #[test] fn match_rest() { assert_js!( @@ -545,7 +579,7 @@ fn go() { // https://github.com/gleam-lang/gleam/issues/1591 #[test] fn not_byte_aligned() { - assert_js!( + assert_js_error!( r#" fn thing() { 4 @@ -560,7 +594,7 @@ fn go() { #[test] fn not_byte_aligned_explicit_sized() { - assert_js!( + assert_js_error!( r#" fn go() { <<256:size(4)>> @@ -583,3 +617,31 @@ fn go() { "#, ); } + +#[test] +fn bit_array_literal_string_constant_is_treated_as_utf8() { + assert_js!(r#"const a = <<"hello", " ", "world">>"#); +} + +#[test] +fn bit_array_literal_string_is_treated_as_utf8() { + assert_js!( + r#" +pub fn main() { + <<"hello", " ", "world">> +}"# + ); +} + +#[test] +fn bit_array_literal_string_pattern_is_treated_as_utf8() { + assert_js!( + r#" +pub fn main() { + case <<>> { + <<"a", "b", _:bytes>> -> 1 + _ -> 2 + } +}"# + ); +} diff --git a/compiler-core/src/javascript/tests/consts.rs b/compiler-core/src/javascript/tests/consts.rs index d9af208a9..067cba62d 100644 --- a/compiler-core/src/javascript/tests/consts.rs +++ b/compiler-core/src/javascript/tests/consts.rs @@ -120,3 +120,9 @@ fn literal_tuple_does_not_get_constant_annotation() { fn literal_nil_does_not_get_constant_annotation() { assert_js!("pub const a = Nil"); } + +// https://github.com/lpil/decode/pull/6 +#[test] +fn constructor_function_in_constant() { + assert_js!("pub const a = Ok"); +} diff --git a/compiler-core/src/javascript/tests/externals.rs b/compiler-core/src/javascript/tests/externals.rs index 020ecf620..dc5ce246d 100644 --- a/compiler-core/src/javascript/tests/externals.rs +++ b/compiler-core/src/javascript/tests/externals.rs @@ -1,4 +1,4 @@ -use crate::{assert_js, assert_module_error, assert_ts_def}; +use crate::{assert_js, assert_js_error, assert_module_error, assert_ts_def}; #[test] fn type_() { @@ -284,7 +284,7 @@ pub fn should_not_be_generated(x: Int) -> Int #[test] fn erlang_bit_patterns() { - assert_js!( + assert_js_error!( r#" pub fn should_not_be_generated(x) { case x { diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__assert.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__assert.snap index cae8c4214..53385f757 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__assert.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__assert.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/assignments.rs +assertion_line: 16 expression: "fn go(x) { let assert 1 = x }" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (x !== 1) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 1, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__assert1.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__assert1.snap index 869797168..35dcde43e 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__assert1.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__assert1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/assignments.rs +assertion_line: 21 expression: "fn go(x) { let assert #(1, 2) = x }" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (x[0] !== 1 || x[1] !== 2) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 1, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__let_assert_string_prefix.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__let_assert_string_prefix.snap index b4cce2a5a..4ce184155 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__let_assert_string_prefix.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__let_assert_string_prefix.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/assignments.rs +assertion_line: 179 expression: "\npub fn main() {\n let assert \"Game \" <> id = \"Game 1\"\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +9,11 @@ export function main() { let $ = "Game 1"; if (!$.startsWith("Game ")) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "main", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: $ } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__nested_binding.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__nested_binding.snap index eaed982b6..f6f22fb6a 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__nested_binding.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__nested_binding.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/assignments.rs +assertion_line: 26 expression: "\nfn go(x) {\n let assert #(a, #(b, c, 2) as t, _, 1) = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (x[1][2] !== 2 || x[3] !== 1) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__returning_literal_subject.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__returning_literal_subject.snap index e21ac84ab..cb7680c59 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__returning_literal_subject.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__returning_literal_subject.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/assignments.rs +assertion_line: 83 expression: "fn go(x) { let assert 1 = x + 1 }" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +9,11 @@ function go(x) { let $ = x + 1; if ($ !== 1) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 1, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: $ } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__tuple_matching.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__tuple_matching.snap index 1f542da1b..985734e71 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__tuple_matching.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__tuple_matching.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/assignments.rs +assertion_line: 5 expression: "\nfn go(x) {\n let assert #(1, 2) = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (x[0] !== 1 || x[1] !== 2) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__variable_renaming.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__variable_renaming.snap index fb898ca40..23ff2146d 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__variable_renaming.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__assignments__variable_renaming.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/assignments.rs +assertion_line: 37 expression: "\n\nfn go(x, wibble) {\n let a = 1\n wibble(a)\n let a = 2\n wibble(a)\n let assert #(a, 3) = x\n let b = a\n wibble(b)\n let c = {\n let a = a\n #(a, b)\n }\n wibble(a)\n // make sure arguments are counted in initial state\n let x = c\n x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -11,11 +12,11 @@ function go(x, wibble) { wibble(a$1); if (x[1] !== 3) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 8, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap new file mode 100644 index 000000000..68092bbfa --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap @@ -0,0 +1,11 @@ +--- +source: compiler-core/src/javascript/tests/bit_arrays.rs +expression: "const a = <<\"hello\", \" \", \"world\">>" +--- +import { toBitArray, stringBits } from "../gleam.mjs"; + +const a = /* @__PURE__ */ toBitArray([ + stringBits("hello"), + stringBits(" "), + stringBits("world"), +]); diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap new file mode 100644 index 000000000..1663e9305 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap @@ -0,0 +1,9 @@ +--- +source: compiler-core/src/javascript/tests/bit_arrays.rs +expression: "\npub fn main() {\n <<\"hello\", \" \", \"world\">>\n}" +--- +import { toBitArray, stringBits } from "../gleam.mjs"; + +export function main() { + return toBitArray([stringBits("hello"), stringBits(" "), stringBits("world")]); +} diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_pattern_is_treated_as_utf8.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_pattern_is_treated_as_utf8.snap new file mode 100644 index 000000000..0329bf5d5 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_array_literal_string_pattern_is_treated_as_utf8.snap @@ -0,0 +1,14 @@ +--- +source: compiler-core/src/javascript/tests/bit_arrays.rs +expression: "\npub fn main() {\n case <<>> {\n <<\"a\", \"b\", _:bytes>> -> 1\n _ -> 2\n }\n}" +--- +import { toBitArray } from "../gleam.mjs"; + +export function main() { + let $ = toBitArray([]); + if ($.byteAt(0) === 0x61 && $.byteAt(1) === 0x62 && $.length >= 2) { + return 1; + } else { + return 2; + } +} diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_arrays_on_js_do_not_support_bits.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_arrays_on_js_do_not_support_bits.snap new file mode 100644 index 000000000..a151b6ab5 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__bit_arrays_on_js_do_not_support_bits.snap @@ -0,0 +1,11 @@ +--- +source: compiler-core/src/javascript/tests/bit_arrays.rs +expression: "\nfn main() {\n case <<1, 2>> {\n <> -> 1\n _ -> 0\n }\n}\n" +--- +error: Unsupported feature for compilation target + ┌─ /src/javascript/error.gleam:4:7 + │ +4 │ <> -> 1 + │ ^^^^^^ + +This bit array segment option in patterns is not supported for JavaScript compilation. diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__discard_sized.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__discard_sized.snap index d20ec46b9..05b74701b 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__discard_sized.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__discard_sized.snap @@ -1,27 +1,28 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -expression: "\nfn go(x) {\n let assert <<_:16, _:8>> = x\n}\n" +assertion_line: 390 +expression: "\nfn go(x) {\n let assert <<_:16, _:8>> = x\n let assert <<_:16-little-signed, _:8>> = x\n}\n" --- import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 3)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } if (!(x.length == 3)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 4, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__empty_match.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__empty_match.snap index 3f9be9149..5d89e4346 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__empty_match.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__empty_match.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 269 expression: "\nfn go(x) {\n let assert <<>> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 0)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_binary_size.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_binary_size.snap index c183f075b..c93717a20 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_binary_size.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_binary_size.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 501 expression: "\nfn go(x) {\n let assert <<_, a:2-bytes>> = x\n let assert <<_, b:bytes-size(2)>> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,22 +8,22 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 3)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } let a = x.binaryFromSlice(1, 3); if (!(x.length == 3)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 4, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_bytes.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_bytes.snap index c1ee4da04..e6595c378 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_bytes.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_bytes.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 280 expression: "\nfn go(x) {\n let assert <<1, y>> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (x.byteAt(0) !== 1 || !(x.length == 2)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_dynamic_size_error.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_dynamic_size_error.snap new file mode 100644 index 000000000..6e9aa03c3 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_dynamic_size_error.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 390 +expression: "\nfn go(x) {\n let n = 16\n let assert <> = x\n}\n" +--- +error: Unsupported feature for compilation target + ┌─ /src/javascript/error.gleam:4:16 + │ +4 │ let assert <> = x + │ ^^^^^^^^^ + +Non-constant size option in patterns is not supported for JavaScript compilation. diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float.snap index 430aa28a1..345d8d7ad 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 413 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 9)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_16_bit_error.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_16_bit_error.snap new file mode 100644 index 000000000..6a603d688 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_16_bit_error.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 500 +expression: "\nfn go(x) {\n let assert <> = x\n}\n" +--- +error: Unsupported feature for compilation target + ┌─ /src/javascript/error.gleam:3:16 + │ +3 │ let assert <> = x + │ ^^^^^^^^^^^^^^^^ + +Float width of 16 bits in patterns is not supported for JavaScript compilation. diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_big_endian.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_big_endian.snap index 37a09031a..8d63cf9e1 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_big_endian.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_big_endian.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 413 +assertion_line: 424 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 9)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_little_endian.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_little_endian.snap index 8f943a617..c85f1b70a 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_little_endian.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_little_endian.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 424 +assertion_line: 435 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 9)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized.snap index d363d1bbe..2e1afbbab 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized.snap @@ -1,18 +1,18 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 290 -expression: "\nfn go(x) {\n let assert <> = x\n let assert <> = x\n let assert <> = x\n let assert <> = x\n let assert <> = x\n let assert <> = x\n let assert <> = x\n let assert <> = x\n}\n" +assertion_line: 446 +expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 5)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized_big_endian.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized_big_endian.snap index 8ddc88f0e..d4bd2450f 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized_big_endian.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized_big_endian.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 446 +assertion_line: 457 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 5)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized_little_endian.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized_little_endian.snap index b899e8a29..a1d591dbc 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized_little_endian.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_float_sized_little_endian.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 457 +assertion_line: 468 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 5)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_non_byte_aligned_size_error.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_non_byte_aligned_size_error.snap new file mode 100644 index 000000000..355734c8d --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_non_byte_aligned_size_error.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 401 +expression: "\nfn go(x) {\n let assert <> = x\n}\n" +--- +error: Unsupported feature for compilation target + ┌─ /src/javascript/error.gleam:3:16 + │ +3 │ let assert <> = x + │ ^^^^^^^^^ + +Non byte aligned integer in patterns is not supported for JavaScript compilation. diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_rest.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_rest.snap index 1413e248b..b5cfa88b8 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_rest.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_rest.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 479 expression: "\nfn go(x) {\n let assert <<_, b:bytes>> = <<1,2,3>>\n}\n" --- import { makeError, toBitArray } from "../gleam.mjs"; @@ -8,11 +9,11 @@ function go(x) { let $ = toBitArray([1, 2, 3]); if (!($.length >= 1)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: $ } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_rest_deprecated.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_rest_deprecated.snap index 1413e248b..3c3b2da67 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_rest_deprecated.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_rest_deprecated.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 490 expression: "\nfn go(x) {\n let assert <<_, b:bytes>> = <<1,2,3>>\n}\n" --- import { makeError, toBitArray } from "../gleam.mjs"; @@ -8,11 +9,11 @@ function go(x) { let $ = toBitArray([1, 2, 3]); if (!($.length >= 1)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: $ } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_signed.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_signed.snap index 90efbeb32..08cb82e58 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_signed.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_signed.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 302 +assertion_line: 313 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 1)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized.snap index 3556dbce0..063825398 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 291 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 3)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian.snap index 7d54e96c0..b420affb8 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 313 +assertion_line: 324 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 2)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian_signed.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian_signed.snap index 4a57d15a7..a4039e029 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian_signed.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian_signed.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 346 +assertion_line: 357 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 2)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian_unsigned.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian_unsigned.snap index c33017ae9..f62be0cee 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian_unsigned.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_big_endian_unsigned.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 335 +assertion_line: 346 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 2)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian.snap index 62a2a7d89..d92d328cd 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 324 +assertion_line: 335 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 2)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian_signed.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian_signed.snap index d43af64a7..68f5a480b 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian_signed.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian_signed.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 368 +assertion_line: 379 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 2)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian_unsigned.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian_unsigned.snap index e1b51c40b..05509a659 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian_unsigned.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_little_endian_unsigned.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 357 +assertion_line: 368 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 2)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_value.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_value.snap index 0ba788a1d..ad0940379 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_value.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_sized_value.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs +assertion_line: 402 expression: "\nfn go(x) {\n let assert <<258:16>> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (x.intFromSlice(0, 2, true, false) !== 258 || !(x.length == 2)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_unsigned.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_unsigned.snap index 582dff800..9a073dab2 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_unsigned.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_unsigned.snap @@ -1,6 +1,6 @@ --- source: compiler-core/src/javascript/tests/bit_arrays.rs -assertion_line: 291 +assertion_line: 302 expression: "\nfn go(x) {\n let assert <> = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -8,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (!(x.length == 1)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_utf8.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_utf8.snap index 7faf02826..24c1adc03 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_utf8.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__match_utf8.snap @@ -20,11 +20,11 @@ function go(x) { !(x.length == 10) ) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__not_byte_aligned.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__not_byte_aligned.snap index db89b02a3..31a4cb93f 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__not_byte_aligned.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__not_byte_aligned.snap @@ -2,8 +2,10 @@ source: compiler-core/src/javascript/tests/bit_arrays.rs expression: "\nfn thing() {\n 4\n}\n\nfn go() {\n <<256:4>>\n}\n" --- -import { toBitArray } from "../gleam.mjs"; +error: Unsupported feature for compilation target + ┌─ /src/javascript/error.gleam:7:5 + │ +7 │ <<256:4>> + │ ^^^^^ -function thing() { - return 4; -} +Non byte aligned array is not supported for JavaScript compilation. diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__not_byte_aligned_explicit_sized.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__not_byte_aligned_explicit_sized.snap index 84b6b230c..f8645d61a 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__not_byte_aligned_explicit_sized.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bit_arrays__not_byte_aligned_explicit_sized.snap @@ -2,4 +2,10 @@ source: compiler-core/src/javascript/tests/bit_arrays.rs expression: "\nfn go() {\n <<256:size(4)>>\n}\n" --- -import { toBitArray } from "../gleam.mjs"; +error: Unsupported feature for compilation target + ┌─ /src/javascript/error.gleam:3:5 + │ +3 │ <<256:size(4)>> + │ ^^^^^^^^^^^ + +Non byte aligned array is not supported for JavaScript compilation. diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__assigning.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__assigning.snap index ac03efac9..a31e9de93 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__assigning.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__assigning.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bools.rs +assertion_line: 52 expression: "\nfn go(x, y) {\n let assert True = x\n let assert False = x\n let assert Nil = y\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,31 +8,31 @@ import { makeError } from "../gleam.mjs"; function go(x, y) { if (!x) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } if (x) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 4, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } if (y) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 5, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: y } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_panic_left.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_panic_left.snap index e4954cec5..f35cfa7a3 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_panic_left.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_panic_left.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bools.rs +assertion_line: 171 expression: "pub fn negate(x) {\n panic && x\n}" --- import { makeError } from "../gleam.mjs"; @@ -11,7 +12,7 @@ export function negate(x) { "my/mod", 2, "negate", - "panic expression evaluated", + "`panic` expression evaluated.", {} ) })() && x; diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_panic_right.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_panic_right.snap index 97a576d07..f73f60084 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_panic_right.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_panic_right.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bools.rs +assertion_line: 162 expression: "pub fn negate(x) {\n x && panic\n}" --- import { makeError } from "../gleam.mjs"; @@ -11,7 +12,7 @@ export function negate(x) { "my/mod", 2, "negate", - "panic expression evaluated", + "`panic` expression evaluated.", {} ) })(); diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_todo_left.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_todo_left.snap index e25384fb3..efc5be823 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_todo_left.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_todo_left.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bools.rs +assertion_line: 189 expression: "pub fn negate(x) {\n todo && x\n}" --- import { makeError } from "../gleam.mjs"; @@ -11,7 +12,7 @@ export function negate(x) { "my/mod", 2, "negate", - "This has not yet been implemented", + "`todo` expression evaluated. This code has not yet been implemented.", {} ) })() && x; diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_todo_right.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_todo_right.snap index cab046f65..9f9376081 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_todo_right.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__binop_todo_right.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bools.rs +assertion_line: 180 expression: "pub fn negate(x) {\n x && todo\n}" --- import { makeError } from "../gleam.mjs"; @@ -11,7 +12,7 @@ export function negate(x) { "my/mod", 2, "negate", - "This has not yet been implemented", + "`todo` expression evaluated. This code has not yet been implemented.", {} ) })(); diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__negate_panic.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__negate_panic.snap index 6d15c3440..03dd28a18 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__negate_panic.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__negate_panic.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bools.rs +assertion_line: 198 expression: "pub fn negate(x) {\n !panic\n}" --- import { makeError } from "../gleam.mjs"; @@ -11,7 +12,7 @@ export function negate(x) { "my/mod", 2, "negate", - "panic expression evaluated", + "`panic` expression evaluated.", {} ) })(); diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__negate_todo.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__negate_todo.snap index 06324a8b2..1237f7dfc 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__negate_todo.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__negate_todo.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bools.rs +assertion_line: 207 expression: "pub fn negate(x) {\n !todo\n}" --- import { makeError } from "../gleam.mjs"; @@ -11,7 +12,7 @@ export function negate(x) { "my/mod", 2, "negate", - "This has not yet been implemented", + "`todo` expression evaluated. This code has not yet been implemented.", {} ) })(); diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__shadowed_bools_and_nil.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__shadowed_bools_and_nil.snap index 99e1f719f..2741db6d3 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__shadowed_bools_and_nil.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__bools__shadowed_bools_and_nil.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/bools.rs +assertion_line: 67 expression: "\npub type True { True False Nil }\nfn go(x, y) {\n let assert True = x\n let assert False = x\n let assert Nil = y\n}\n" --- import { CustomType as $CustomType, makeError } from "../gleam.mjs"; @@ -13,31 +14,31 @@ export class Nil extends $CustomType {} function go(x, y) { if (!(x instanceof True)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 4, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } if (!(x instanceof False)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 5, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } if (!(y instanceof Nil)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 6, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: y } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__case__following_todo.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__case__following_todo.snap index 6922cd205..15824ffee 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__case__following_todo.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__case__following_todo.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/case.rs +assertion_line: 20 expression: "\nfn go(x) {\n case x {\n True -> todo\n _ -> 1\n }\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -11,7 +12,7 @@ function go(x) { "my/mod", 4, "go", - "This has not yet been implemented", + "`todo` expression evaluated. This code has not yet been implemented.", {} ) } else { diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__constructor_function_in_constant.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__constructor_function_in_constant.snap new file mode 100644 index 000000000..b1361dbf2 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__constructor_function_in_constant.snap @@ -0,0 +1,8 @@ +--- +source: compiler-core/src/javascript/tests/consts.rs +assertion_line: 127 +expression: pub const a = Ok +--- +import { Ok } from "../gleam.mjs"; + +export const a = (var0) => { return new Ok(var0); }; diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__imported_aliased_ok.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__imported_aliased_ok.snap index ff0e4333b..a92ca90d4 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__imported_aliased_ok.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__imported_aliased_ok.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/consts.rs +assertion_line: 16 expression: "import gleam.{Ok as Y}\n\npub type X {\n Ok\n}\n\npub const y = Y\n" --- import * as $gleam from "../gleam.mjs"; @@ -7,4 +8,4 @@ import { Ok as Y, CustomType as $CustomType } from "../gleam.mjs"; export class Ok extends $CustomType {} -export const y = /* @__PURE__ */ new Y(); +export const y = (var0) => { return new Y(var0); }; diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__imported_ok.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__imported_ok.snap index 7d3e72aa3..f99eb35f6 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__imported_ok.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__consts__imported_ok.snap @@ -1,10 +1,11 @@ --- source: compiler-core/src/javascript/tests/consts.rs +assertion_line: 30 expression: "import gleam\n\npub type X {\n Ok\n}\n\npub const y = gleam.Ok\n" --- import * as $gleam from "../gleam.mjs"; -import { CustomType as $CustomType } from "../gleam.mjs"; +import { Ok, CustomType as $CustomType } from "../gleam.mjs"; export class Ok extends $CustomType {} -export const y = /* @__PURE__ */ new $gleam.Ok(); +export const y = (var0) => { return new Ok(var0); }; diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__custom_types__destructure_custom_type_with_named_fields.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__custom_types__destructure_custom_type_with_named_fields.snap index ff4e30804..ad3186fe6 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__custom_types__destructure_custom_type_with_named_fields.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__custom_types__destructure_custom_type_with_named_fields.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/custom_types.rs +assertion_line: 278 expression: "\ntype Cat {\n Cat(name: String, cuteness: Int)\n}\n\nfn go(cat) {\n let Cat(x, y) = cat\n let Cat(name: x, ..) = cat\n let assert Cat(cuteness: 4, name: x) = cat\n x\n}\n\n" --- import { CustomType as $CustomType, makeError } from "../gleam.mjs"; @@ -18,11 +19,11 @@ function go(cat) { let x$1 = cat.name; if (!(cat instanceof Cat) || cat.cuteness !== 4) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 9, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: cat } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__attribute_erlang.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__attribute_erlang.snap index d52d07ff5..e668e6419 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__attribute_erlang.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__attribute_erlang.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/externals.rs +assertion_line: 141 expression: "\n@external(erlang, \"one\", \"one_erl\")\npub fn one(x: Int) -> Int {\n todo\n}\n\npub fn main() {\n one(1)\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -10,7 +11,7 @@ export function one(x) { "my/mod", 4, "one", - "This has not yet been implemented", + "`todo` expression evaluated. This code has not yet been implemented.", {} ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__erlang_bit_patterns.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__erlang_bit_patterns.snap index ca9f37b8e..0f3716285 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__erlang_bit_patterns.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__erlang_bit_patterns.snap @@ -2,4 +2,10 @@ source: compiler-core/src/javascript/tests/externals.rs expression: "\npub fn should_not_be_generated(x) {\n case x {\n <<_, rest:bits>> -> rest\n _ -> x\n }\n}\n" --- -export {} +error: Unsupported feature for compilation target + ┌─ /src/javascript/error.gleam:4:10 + │ +4 │ <<_, rest:bits>> -> rest + │ ^^^^^^^^^ + +This bit array segment option in patterns is not supported for JavaScript compilation. diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__private_attribute_erlang.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__private_attribute_erlang.snap index ccf36da21..2ca556ed8 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__private_attribute_erlang.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__externals__private_attribute_erlang.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/externals.rs +assertion_line: 190 expression: "\n@external(erlang, \"one\", \"one_erl\")\nfn one(x: Int) -> Int {\n todo\n}\n\npub fn main() {\n one(1)\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -10,7 +11,7 @@ function one(x) { "my/mod", 4, "one", - "This has not yet been implemented", + "`todo` expression evaluated. This code has not yet been implemented.", {} ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__lists__list_destructuring.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__lists__list_destructuring.snap index 50d928f07..90b7310b4 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__lists__list_destructuring.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__lists__list_destructuring.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/lists.rs +assertion_line: 62 expression: "\nfn go(x, y) {\n let assert [] = x\n let assert [a] = x\n let assert [1, 2] = x\n let assert [_, #(3, b)] = y\n let assert [head, ..tail] = y\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,53 +8,53 @@ import { makeError } from "../gleam.mjs"; function go(x, y) { if (!x.hasLength(0)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } if (!x.hasLength(1)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 4, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } let a = x.head; if (!x.hasLength(2) || x.head !== 1 || x.tail.head !== 2) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 5, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } if (!y.hasLength(2) || y.tail.head[0] !== 3) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 6, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: y } ) } let b = y.tail.head[1]; if (!y.atLeastLength(1)) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 7, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: y } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__int_patterns.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__int_patterns.snap index 0ccff3866..99b92d3f7 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__int_patterns.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__int_patterns.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/numbers.rs +assertion_line: 146 expression: "\nfn go(x) {\n let assert 4 = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (x !== 4) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__preceeding_zeros_float_pattern.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__preceeding_zeros_float_pattern.snap index 379ea944a..5703bf5e9 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__preceeding_zeros_float_pattern.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__preceeding_zeros_float_pattern.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/numbers.rs +assertion_line: 308 expression: "\nfn main(x) {\n let assert 09_179.1 = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function main(x) { if (x !== 9_179.1) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "main", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__preceeding_zeros_int_pattern.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__preceeding_zeros_int_pattern.snap index 9045191b8..f3e1cefe3 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__preceeding_zeros_int_pattern.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__numbers__preceeding_zeros_int_pattern.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/numbers.rs +assertion_line: 296 expression: "\nfn main(x) {\n let assert 09_179 = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function main(x) { if (x !== 9_179) { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "main", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__as_expression.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__as_expression.snap index 578a66d13..410dea2c7 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__as_expression.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__as_expression.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/panic.rs +assertion_line: 39 expression: "\nfn go(f) {\n let boop = panic\n f(panic)\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -11,7 +12,7 @@ function go(f) { "my/mod", 3, "go", - "panic expression evaluated", + "`panic` expression evaluated.", {} ) })(); @@ -22,7 +23,7 @@ function go(f) { "my/mod", 4, "go", - "panic expression evaluated", + "`panic` expression evaluated.", {} ) })(), diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__bare.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__bare.snap index eebf96832..b39cbcc28 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__bare.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__bare.snap @@ -1,9 +1,17 @@ --- source: compiler-core/src/javascript/tests/panic.rs +assertion_line: 5 expression: "\nfn go() {\n panic\n}\n" --- import { makeError } from "../gleam.mjs"; function go() { - throw makeError("panic", "my/mod", 3, "go", "panic expression evaluated", {}) + throw makeError( + "panic", + "my/mod", + 3, + "go", + "`panic` expression evaluated.", + {} + ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__case.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__case.snap index 458d94e34..ae3727352 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__case.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__case.snap @@ -12,7 +12,7 @@ function go(x) { "my/mod", 4, "go", - "panic expression evaluated", + "`panic` expression evaluated.", {} ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__pipe.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__pipe.snap index aeb7c51d3..f20bf2855 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__pipe.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__pipe.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/panic.rs +assertion_line: 51 expression: "\nfn go(f) {\n f |> panic\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -12,7 +13,7 @@ function go(f) { "my/mod", 3, "go", - "panic expression evaluated", + "`panic` expression evaluated.", {} ) })()(_pipe); diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__sequence.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__sequence.snap index 4451acc11..fffa6f60a 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__sequence.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__panic__sequence.snap @@ -1,10 +1,18 @@ --- source: compiler-core/src/javascript/tests/panic.rs +assertion_line: 62 expression: "\nfn go(at_the_disco) {\n panic\n at_the_disco\n}\n" --- import { makeError } from "../gleam.mjs"; function go(at_the_disco) { - throw makeError("panic", "my/mod", 3, "go", "panic expression evaluated", {}) + throw makeError( + "panic", + "my/mod", + 3, + "go", + "`panic` expression evaluated.", + {} + ) return at_the_disco; } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__strings__string_patterns.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__strings__string_patterns.snap index 3f61f3e30..e5692e4a5 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__strings__string_patterns.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__strings__string_patterns.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/strings.rs +assertion_line: 60 expression: "\nfn go(x) {\n let assert \"Hello\" = x\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -7,11 +8,11 @@ import { makeError } from "../gleam.mjs"; function go(x) { if (x !== "Hello") { throw makeError( - "assignment_no_match", + "let_assert", "my/mod", 3, "go", - "Assignment pattern did not match", + "Pattern match failed, no pattern matched the value.", { value: x } ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__todo__without_message.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__todo__without_message.snap index 2aeb6d5a2..1b55f2601 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__todo__without_message.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__todo__without_message.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/todo.rs +assertion_line: 5 expression: "\nfn go() {\n todo\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -10,7 +11,7 @@ function go() { "my/mod", 3, "go", - "This has not yet been implemented", + "`todo` expression evaluated. This code has not yet been implemented.", {} ) } diff --git a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__use___no_callback_body.snap b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__use___no_callback_body.snap index 8450c6e10..762193454 100644 --- a/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__use___no_callback_body.snap +++ b/compiler-core/src/javascript/tests/snapshots/glistix_core__javascript__tests__use___no_callback_body.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/javascript/tests/use_.rs +assertion_line: 56 expression: "\npub fn main() {\n let thingy = fn(f) { f() }\n use <- thingy()\n}\n" --- import { makeError } from "../gleam.mjs"; @@ -13,7 +14,7 @@ export function main() { "my/mod", 4, "", - "This has not yet been implemented", + "`todo` expression evaluated. This code has not yet been implemented.", {} ) }, diff --git a/compiler-core/src/javascript/typescript.rs b/compiler-core/src/javascript/typescript.rs index 6bbf83fe8..658a41fcc 100644 --- a/compiler-core/src/javascript/typescript.rs +++ b/compiler-core/src/javascript/typescript.rs @@ -84,20 +84,20 @@ fn collect_generic_usages<'a>( mut ids: HashMap, types: impl IntoIterator>, ) -> HashMap { - for typ in types { - generic_ids(typ, &mut ids); + for type_ in types { + generic_ids(type_, &mut ids); } ids } fn generic_ids(type_: &Type, ids: &mut HashMap) { match type_ { - Type::Var { type_: typ } => match typ.borrow().deref() { + Type::Var { type_ } => match type_.borrow().deref() { TypeVar::Unbound { id, .. } | TypeVar::Generic { id, .. } => { let count = ids.entry(*id).or_insert(0); *count += 1; } - TypeVar::Link { type_: typ } => generic_ids(typ, ids), + TypeVar::Link { type_ } => generic_ids(type_, ids), }, Type::Named { args, .. } => { for arg in args { @@ -555,7 +555,7 @@ impl<'a> TypeScriptGenerator<'a> { generic_usages: Option<&HashMap>, ) -> Document<'static> { match type_ { - Type::Var { type_: typ } => self.print_var(&typ.borrow(), generic_usages, false), + Type::Var { type_ } => self.print_var(&type_.borrow(), generic_usages, false), Type::Named { name, module, args, .. @@ -573,7 +573,7 @@ impl<'a> TypeScriptGenerator<'a> { fn do_print_force_generic_param(&mut self, type_: &Type) -> Document<'static> { match type_ { - Type::Var { type_: typ } => self.print_var(&typ.borrow(), None, true), + Type::Var { type_ } => self.print_var(&type_.borrow(), None, true), Type::Named { name, module, args, .. @@ -610,7 +610,7 @@ impl<'a> TypeScriptGenerator<'a> { } } }, - TypeVar::Link { type_: typ } => self.do_print(typ, generic_usages), + TypeVar::Link { type_ } => self.do_print(type_, generic_usages), } } diff --git a/compiler-core/src/language_server.rs b/compiler-core/src/language_server.rs index b3970a5e4..fbc80082c 100644 --- a/compiler-core/src/language_server.rs +++ b/compiler-core/src/language_server.rs @@ -1,6 +1,7 @@ mod code_action; mod compiler; mod completer; +mod edits; mod engine; mod feedback; mod files; diff --git a/compiler-core/src/language_server/code_action.rs b/compiler-core/src/language_server/code_action.rs index 392850054..44ede5a72 100644 --- a/compiler-core/src/language_server/code_action.rs +++ b/compiler-core/src/language_server/code_action.rs @@ -10,10 +10,11 @@ use crate::{ AssignName, AssignmentKind, CallArg, ImplicitCallArgOrigin, Pattern, SrcSpan, TypedExpr, TypedPattern, TypedRecordUpdateArg, }, - build::Module, + build::{Located, Module}, line_numbers::LineNumbers, parse::extra::ModuleExtra, - type_::{FieldMap, ModuleValueConstructor, Type, TypedCallArg}, + type_::{self, error::ModuleSuggestion, FieldMap, ModuleValueConstructor, Type, TypedCallArg}, + Error, }; use ecow::EcoString; use im::HashMap; @@ -21,6 +22,7 @@ use itertools::Itertools; use lsp_types::{CodeAction, CodeActionKind, CodeActionParams, TextEdit, Url}; use super::{ + edits::{add_newlines_after_import, get_import_edit, position_of_first_definition_if_import}, engine::{overlaps, within}, src_span_to_lsp_range, }; @@ -119,7 +121,7 @@ impl<'ast> ast::visit::Visit<'ast> for RedundantTupleInCaseSubject<'_> { fn visit_typed_expr_case( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, subjects: &'ast [TypedExpr], clauses: &'ast [ast::TypedClause], ) { @@ -164,7 +166,7 @@ impl<'ast> ast::visit::Visit<'ast> for RedundantTupleInCaseSubject<'_> { self.edits.extend(clause_edits); } - ast::visit::visit_typed_expr_case(self, location, typ, subjects, clauses) + ast::visit::visit_typed_expr_case(self, location, type_, subjects, clauses) } } @@ -605,7 +607,7 @@ impl<'ast> ast::visit::Visit<'ast> for FillInMissingLabelledArgs<'ast> { fn visit_typed_expr_call( &mut self, location: &'ast SrcSpan, - typ: &'ast Arc, + type_: &'ast Arc, fun: &'ast TypedExpr, args: &'ast [TypedCallArg], ) { @@ -632,6 +634,278 @@ impl<'ast> ast::visit::Visit<'ast> for FillInMissingLabelledArgs<'ast> { // containing the current selection so we can't stop at the first call // we find (the outermost one) and have to keep traversing it in case // we're inside a nested call. - visit_typed_expr_call(self, location, typ, fun, args) + visit_typed_expr_call(self, location, type_, fun, args) + } +} + +struct MissingImport { + location: SrcSpan, + suggestions: Vec, +} + +struct ImportSuggestion { + // The name to replace with, if the user made a typo + name: EcoString, + // The optional module to import, if suggesting an importable module + import: Option, +} + +pub fn code_action_import_module( + module: &Module, + params: &CodeActionParams, + error: &Option, + actions: &mut Vec, +) { + let uri = ¶ms.text_document.uri; + let Some(Error::Type { errors, .. }) = error else { + return; + }; + + let missing_imports = errors + .into_iter() + .filter_map(|e| match e { + type_::Error::UnknownModule { + location, + suggestions, + .. + } => suggest_imports(*location, suggestions), + _ => None, + }) + .collect_vec(); + + if missing_imports.is_empty() { + return; + } + + let line_numbers = LineNumbers::new(&module.code); + let first_import_pos = position_of_first_definition_if_import(module, &line_numbers); + let first_is_import = first_import_pos.is_some(); + let import_location = first_import_pos.unwrap_or_default(); + + let after_import_newlines = add_newlines_after_import( + import_location, + first_is_import, + &line_numbers, + &module.code, + ); + + for missing_import in missing_imports { + let range = src_span_to_lsp_range(missing_import.location, &line_numbers); + if !overlaps(params.range, range) { + continue; + } + + for suggestion in missing_import.suggestions { + let mut edits = vec![TextEdit { + range, + new_text: suggestion.name.to_string(), + }]; + if let Some(import) = &suggestion.import { + edits.push(get_import_edit( + import_location, + import, + &after_import_newlines, + )) + }; + + let title = if let Some(import) = &suggestion.import { + &format!("Import `{import}`") + } else { + &format!("Did you mean `{}`", suggestion.name) + }; + + CodeActionBuilder::new(title) + .kind(CodeActionKind::QUICKFIX) + .changes(uri.clone(), edits) + .preferred(true) + .push_to(actions); + } + } +} + +fn suggest_imports( + location: SrcSpan, + importable_modules: &[ModuleSuggestion], +) -> Option { + let suggestions = importable_modules + .iter() + .map(|suggestion| { + let imported_name = suggestion.last_name_component(); + match suggestion { + ModuleSuggestion::Importable(name) => ImportSuggestion { + name: imported_name.into(), + import: Some(name.clone()), + }, + ModuleSuggestion::Imported(_) => ImportSuggestion { + name: imported_name.into(), + import: None, + }, + } + }) + .collect_vec(); + + if suggestions.is_empty() { + None + } else { + Some(MissingImport { + location, + suggestions, + }) + } +} + +pub fn code_action_add_missing_patterns( + module: &Module, + params: &CodeActionParams, + error: &Option, + actions: &mut Vec, +) { + let uri = ¶ms.text_document.uri; + let Some(Error::Type { errors, .. }) = error else { + return; + }; + let missing_patterns = errors + .iter() + .filter_map(|error| match error { + type_::Error::InexhaustiveCaseExpression { location, missing } => { + Some((*location, missing)) + } + _ => None, + }) + .collect_vec(); + + if missing_patterns.is_empty() { + return; + } + + let line_numbers = LineNumbers::new(&module.code); + + for (location, missing) in missing_patterns { + let range = src_span_to_lsp_range(location, &line_numbers); + if !overlaps(params.range, range) { + return; + } + + let mut edits = Vec::new(); + + let Some(Located::Expression(TypedExpr::Case { + clauses, subjects, .. + })) = module.find_node(location.start) + else { + continue; + }; + + // Find the start of the line. We can't just use the start of the case + // expression for cases like: + // + //```gleam + // let value = case a {} + //``` + // + // Here, the start of the expression is part-way through the line, meaning + // we think we are more indented than we actually are + // + let mut indent_size = 0; + let line_start = *line_numbers + .line_starts + .get(range.start.line as usize) + .expect("Line number should be valid"); + let chars = module.code.chars(); + let mut chars = chars.skip(line_start as usize); + // Count indentation + while chars.next() == Some(' ') { + indent_size += 1; + } + + let indent = " ".repeat(indent_size); + + // Insert the missing patterns just after the final clause, or just before + // the closing brace if there are no clauses + let insert_span = clauses + .last() + .map(|clause| SrcSpan { + start: clause.location.end, + end: clause.location.end, + }) + .unwrap_or(SrcSpan { + start: location.end - 1, + end: location.end - 1, + }); + + let insert_range = src_span_to_lsp_range(insert_span, &line_numbers); + + for pattern in missing { + let new_text = format!("\n{indent} {pattern} -> todo"); + edits.push(TextEdit { + range: insert_range, + new_text, + }) + } + + // Add a newline + indent after the last pattern if there are no clauses + // + // This improves the generated code for this case: + // ```gleam + // case True {} + // ``` + // This produces: + // ```gleam + // case True { + // True -> todo + // False -> todo + // } + // ``` + // Instead of: + // ```gleam + // case True { + // True -> todo + // False -> todo} + // ``` + // + if clauses.is_empty() { + let last_subject_location = subjects + .last() + .expect("Case expressions have at least one subject") + .location() + .end; + + // Find the opening brace of the case expression + + // Calculate the number of characters from the start of the line to the end of the + // last subject, to skip, so we can find the opening brace. + // That is: the location we want to get to, minus the start of the line which we skipped to begin with, + // minus the number we skipped for the indent, minus one more because we go one past the end of indentation + let num_to_skip = last_subject_location - line_start - indent_size as u32 - 1; + let chars = chars.skip(num_to_skip as usize); + let mut start_brace_location = last_subject_location; + for char in chars { + start_brace_location += 1; + if char == '{' { + break; + } + } + + let range = src_span_to_lsp_range( + SrcSpan::new(start_brace_location, insert_span.start), + &line_numbers, + ); + + // Remove any blank spaces/lines between the start brace and end brace + edits.push(TextEdit { + range, + new_text: String::new(), + }); + + edits.push(TextEdit { + range: insert_range, + new_text: format!("\n{indent}"), + }) + } + + CodeActionBuilder::new("Add missing patterns") + .kind(CodeActionKind::QUICKFIX) + .changes(uri.clone(), edits) + .preferred(true) + .push_to(actions); } } diff --git a/compiler-core/src/language_server/compiler.rs b/compiler-core/src/language_server/compiler.rs index 2517a85ff..ab5b6ea56 100644 --- a/compiler-core/src/language_server/compiler.rs +++ b/compiler-core/src/language_server/compiler.rs @@ -15,7 +15,7 @@ use crate::{ warning::VectorWarningEmitterIO, Error, Result, Warning, }; -use std::{collections::HashMap, sync::Arc}; +use std::{collections::HashMap, rc::Rc}; use camino::Utf8PathBuf; @@ -32,7 +32,7 @@ pub struct LspProjectCompiler { pub sources: HashMap, /// The storage for the warning emitter. - pub warnings: Arc, + pub warnings: Rc, /// A lock to ensure that multiple instances of the LSP don't try and use /// build directory at the same time. @@ -50,10 +50,9 @@ where io: IO, locker: Box, ) -> Result { - let telemetry = NullTelemetry; let target = config.target; let name = config.name.clone(); - let warnings = Arc::new(VectorWarningEmitterIO::default()); + let warnings = Rc::new(VectorWarningEmitterIO::default()); // The build caches do not contain all the information we need in the // LSP (e.g. the typed AST) so delete the caches for the top level @@ -70,13 +69,15 @@ where mode: Mode::Lsp, target: None, codegen: build::Codegen::None, + compile: build::Compile::All, root_target_support: TargetSupport::Enforced, + no_print_progress: false, }; let mut project_compiler = ProjectCompiler::new( config, options, manifest.packages, - Box::new(telemetry), + &NullTelemetry, warnings.clone(), paths, io, diff --git a/compiler-core/src/language_server/completer.rs b/compiler-core/src/language_server/completer.rs index c7d006db1..d348d0de1 100644 --- a/compiler-core/src/language_server/completer.rs +++ b/compiler-core/src/language_server/completer.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{collections::HashMap, sync::Arc}; use ecow::EcoString; use itertools::Itertools; @@ -10,19 +10,25 @@ use lsp_types::{ use strum::IntoEnumIterator; use crate::{ - ast::{CallArg, Definition, Import, Publicity, TypedDefinition, TypedExpr}, + ast::{self, Arg, CallArg, Definition, Function, Pattern, Publicity, TypedExpr}, build::Module, io::{CommandExecutor, FileSystemReader, FileSystemWriter}, line_numbers::LineNumbers, type_::{ - collapse_links, pretty::Printer, AccessorsMap, FieldMap, ModuleInterface, PreludeType, - Type, TypeConstructor, ValueConstructorVariant, + self, collapse_links, pretty::Printer, AccessorsMap, FieldMap, ModuleInterface, + PreludeType, Type, TypeConstructor, ValueConstructorVariant, PRELUDE_MODULE_NAME, }, Result, }; use super::{ - compiler::LspProjectCompiler, files::FileSystemProxy, DownloadDependencies, MakeLocker, + compiler::LspProjectCompiler, + edits::{ + add_newlines_after_import, get_import, get_import_edit, + position_of_first_definition_if_import, Newlines, + }, + files::FileSystemProxy, + DownloadDependencies, MakeLocker, }; // Represents the kind/specificity of completion that is being requested. @@ -36,7 +42,7 @@ enum CompletionKind { LocallyDefined, // Values or types defined in an already imported module ImportedModule, - // Types defined in the prelude + // Types or values defined in the prelude Prelude, // Types defined in a module that has not been imported ImportableModule, @@ -65,11 +71,6 @@ enum TypeCompletionForm { Default, } -enum Newlines { - Single, - Double, -} - pub struct Completer<'a, IO> { /// The direct buffer source code src: &'a EcoString, @@ -131,6 +132,7 @@ where .get(..cursor as usize) .and_then(|line| line.rsplit_once(valid_phrase_char).map(|r| r.1)) .unwrap_or(""); + // Get part of phrase following cursor let after = self .src @@ -302,7 +304,7 @@ where } // Get all the modules that can be imported that have not already been imported. - fn completable_modules_for_import(&'a self) -> Vec<(&EcoString, &ModuleInterface)> { + fn completable_modules_for_import(&self) -> Vec<(&EcoString, &ModuleInterface)> { let mut direct_dep_packages: std::collections::HashSet<&EcoString> = std::collections::HashSet::from_iter( self.compiler.project_compiler.config.dependencies.keys(), @@ -465,9 +467,17 @@ where } // Importable modules - let (first_import_pos, first_is_import) = self.first_import_in_module(); - let after_import_newlines = - self.add_newlines_after_import(first_import_pos, first_is_import); + let first_import_pos = + position_of_first_definition_if_import(self.module, &self.src_line_numbers); + let first_is_import = first_import_pos.is_some(); + let import_location = first_import_pos.unwrap_or_default(); + + let after_import_newlines = add_newlines_after_import( + import_location, + first_is_import, + &self.src_line_numbers, + self.src, + ); for (module_full_name, module) in self.completable_modules_for_import() { // Do not try to import the prelude. if module_full_name == "gleam" { @@ -503,7 +513,7 @@ where ); add_import_to_completion( &mut completion, - first_import_pos, + import_location, module_full_name, &after_import_newlines, ); @@ -522,10 +532,60 @@ where let (insert_range, module_select) = surrounding_completion; + let mut push_prelude_completion = |label: &str, kind| { + let label = label.to_string(); + let sort_text = Some(sort_text(CompletionKind::Prelude, &label)); + completions.push(CompletionItem { + label, + detail: Some(PRELUDE_MODULE_NAME.into()), + kind: Some(kind), + sort_text, + ..Default::default() + }); + }; + + // Prelude values + for type_ in PreludeType::iter() { + match type_ { + PreludeType::Bool => { + push_prelude_completion("True", CompletionItemKind::ENUM_MEMBER); + push_prelude_completion("False", CompletionItemKind::ENUM_MEMBER); + } + PreludeType::Nil => { + push_prelude_completion("Nil", CompletionItemKind::ENUM_MEMBER); + } + PreludeType::Result => { + push_prelude_completion("Ok", CompletionItemKind::CONSTRUCTOR); + push_prelude_completion("Error", CompletionItemKind::CONSTRUCTOR); + } + PreludeType::BitArray + | PreludeType::Float + | PreludeType::Int + | PreludeType::List + | PreludeType::String + | PreludeType::UtfCodepoint => {} + } + } + // Module values // Do not complete direct module values if the user has already started typing a module select. // e.x. when the user has typed mymodule.| we know local module values are no longer relevant if module_select.is_none() { + let cursor = self + .src_line_numbers + .byte_index(self.cursor_position.line, self.cursor_position.character); + + // Find the function that the cursor is in and push completions for + // its arguments and local variables. + if let Some(fun) = self.module.ast.definitions.iter().find_map(|d| match d { + Definition::Function(f) if f.full_location().contains(cursor) => Some(f), + _ => None, + }) { + completions.extend( + LocalCompletion::new(mod_name, insert_range, cursor).fn_completions(fun), + ); + } + for (name, value) in &self.module.ast.type_info.values { // Here we do not check for the internal attribute: we always want // to show autocompletions for values defined in the same module, @@ -598,9 +658,16 @@ where } // Importable modules - let (first_import_pos, first_is_import) = self.first_import_in_module(); - let after_import_newlines = - self.add_newlines_after_import(first_import_pos, first_is_import); + let first_import_pos = + position_of_first_definition_if_import(self.module, &self.src_line_numbers); + let first_is_import = first_import_pos.is_some(); + let import_location = first_import_pos.unwrap_or_default(); + let after_import_newlines = add_newlines_after_import( + import_location, + first_is_import, + &self.src_line_numbers, + self.src, + ); for (module_full_name, module) in self.completable_modules_for_import() { // Do not try to import the prelude. if module_full_name == "gleam" { @@ -636,7 +703,7 @@ where add_import_to_completion( &mut completion, - first_import_pos, + import_location, module_full_name, &after_import_newlines, ); @@ -652,7 +719,7 @@ where &'a self, importable_modules: &'a im::HashMap, type_: Arc, - ) -> Option<&AccessorsMap> { + ) -> Option<&'a AccessorsMap> { let type_ = collapse_links(type_); match type_.as_ref() { Type::Named { name, module, .. } => importable_modules @@ -665,10 +732,10 @@ where /// Provides completions for field accessors when the context being editted /// is a custom type instance - pub fn completion_field_accessors(&'a self, typ: Arc) -> Vec { + pub fn completion_field_accessors(&'a self, type_: Arc) -> Vec { self.type_accessors_from_modules( self.compiler.project_compiler.get_importable_modules(), - typ, + type_, ) .map(|accessors_map| { accessors_map @@ -749,53 +816,12 @@ where Publicity::Private => false, // We only skip internal types if those are not defined in // the root package. - Publicity::Internal if package != self.root_package_name() => false, - Publicity::Internal => true, + Publicity::Internal { .. } if package != self.root_package_name() => false, + Publicity::Internal { .. } => true, // We never skip public types. Publicity::Public => true, } } - - // Gets the position of the import statement if it's the first definition in the module. - // If the 1st definition is not an import statement, then it returns the 1st line. - // 2nd element in the pair is true if the first definition is an import statement. - fn first_import_in_module(&'a self) -> (Position, bool) { - // As "self.module.ast.definitions" could be sorted, let's find the actual first definition by position. - let first_definition = self - .module - .ast - .definitions - .iter() - .min_by(|a, b| a.location().start.cmp(&b.location().start)); - let import = first_definition.and_then(get_import); - let import_start = import.map_or(0, |i| i.location.start); - let import_line = self.module_line_numbers.line_number(import_start); - (Position::new(import_line - 1, 0), import.is_some()) - } - - // Returns how many newlines should be added after an import statement. By default `Newlines::Single`, - // but if there's not any import statement, it returns `Newlines::Double`. - // - // * ``import_location`` - The position of the first import statement in the source code. - fn add_newlines_after_import( - &'a self, - import_location: Position, - has_imports: bool, - ) -> Newlines { - let import_start_cursor = self - .src_line_numbers - .byte_index(import_location.line, import_location.character); - let is_new_line = self - .src - .chars() - .nth(import_start_cursor as usize) - .unwrap_or_default() - == '\n'; - match !has_imports && !is_new_line { - true => Newlines::Double, - false => Newlines::Single, - } - } } fn add_import_to_completion( @@ -804,17 +830,11 @@ fn add_import_to_completion( module_full_name: &EcoString, insert_newlines: &Newlines, ) { - let new_lines = match insert_newlines { - Newlines::Single => "\n", - Newlines::Double => "\n\n", - }; - item.additional_text_edits = Some(vec![TextEdit { - range: Range { - start: import_location, - end: import_location, - }, - new_text: ["import ", module_full_name, new_lines].concat(), - }]); + item.additional_text_edits = Some(vec![get_import_edit( + import_location, + module_full_name, + insert_newlines, + )]); } fn type_completion( @@ -830,7 +850,7 @@ fn type_completion( None => name.to_string(), }; - let kind = Some(if type_.typ.is_variable() { + let kind = Some(if type_.type_.is_variable() { CompletionItemKind::VARIABLE } else { CompletionItemKind::CLASS @@ -856,7 +876,7 @@ fn value_completion( module_qualifier: Option<&str>, module_name: &str, name: &str, - value: &crate::type_::ValueConstructor, + value: &type_::ValueConstructor, insert_range: Range, priority: CompletionKind, ) -> CompletionItem { @@ -901,6 +921,38 @@ fn value_completion( } } +fn local_value_completion( + module_name: &str, + name: &str, + type_: Arc, + insert_range: Range, +) -> CompletionItem { + let label = name.to_string(); + let type_ = Printer::new().pretty_print(&type_, 0); + + let documentation = Documentation::MarkupContent(MarkupContent { + kind: MarkupKind::Markdown, + value: String::from("A locally defined variable."), + }); + + CompletionItem { + label: label.clone(), + kind: Some(CompletionItemKind::VARIABLE), + detail: Some(type_), + label_details: Some(CompletionItemLabelDetails { + detail: None, + description: Some(module_name.into()), + }), + documentation: Some(documentation), + sort_text: Some(sort_text(CompletionKind::LocallyDefined, &label)), + text_edit: Some(CompletionTextEdit::Edit(TextEdit { + range: insert_range, + new_text: label.clone(), + })), + ..Default::default() + } +} + fn field_completion(label: &str, type_: Arc) -> CompletionItem { let type_ = Printer::new().pretty_print(&type_, 0); @@ -913,9 +965,134 @@ fn field_completion(label: &str, type_: Arc) -> CompletionItem { } } -fn get_import(statement: &TypedDefinition) -> Option<&Import> { - match statement { - Definition::Import(import) => Some(import), - _ => None, +pub struct LocalCompletion<'a> { + mod_name: &'a str, + insert_range: Range, + cursor: u32, + completions: HashMap, +} + +impl<'a> LocalCompletion<'a> { + pub fn new(mod_name: &'a str, insert_range: Range, cursor: u32) -> Self { + Self { + mod_name, + insert_range, + cursor, + completions: HashMap::new(), + } + } + + /// Generates completion items for a given function, including its arguments + /// and local variables. + pub fn fn_completions( + mut self, + fun: &'a Function, TypedExpr>, + ) -> Vec { + // Add function arguments to completions + self.visit_fn_args(&fun.arguments); + + // Visit the function body statements + for statement in &fun.body { + // We only want to suggest local variables that are defined before + // the cursor + if statement.location().start >= self.cursor { + continue; + } + + // Visit the statement to find local variables + ast::visit::visit_typed_statement(&mut self, statement); + } + + self.completions.into_values().collect_vec() + } + + fn visit_fn_args(&mut self, args: &[Arg>]) { + for arg in args { + if let Some(name) = arg.get_variable_name() { + self.push_completion(name, arg.type_.clone()); + } + } + } + + fn push_completion(&mut self, name: &EcoString, type_: Arc) { + if name.is_empty() || name.starts_with('_') { + return; + } + + _ = self.completions.insert( + name.clone(), + local_value_completion(self.mod_name, name, type_, self.insert_range), + ); + } +} + +impl<'ast> ast::visit::Visit<'ast> for LocalCompletion<'_> { + /// Visits a typed assignment, selectively processing either the value or the pattern + /// based on the cursor position. + /// - If the cursor is within the assignment It visits only the value expression. + /// This avoids suggesting variables that are being defined in the assignment itself. + /// - If the cursor is outside the assignment It visits only the pattern. + /// This prevents suggesting variables that might be out of scope. + fn visit_typed_assignment(&mut self, assignment: &'ast ast::TypedAssignment) { + if assignment.location.contains(self.cursor) { + self.visit_typed_expr(&assignment.value); + } else { + self.visit_typed_pattern(&assignment.pattern); + } + } + + fn visit_typed_expr_fn( + &mut self, + _: &'ast ast::SrcSpan, + _: &'ast Arc, + _: &'ast bool, + args: &'ast [ast::TypedArg], + body: &'ast [ast::TypedStatement], + _: &'ast Option, + ) { + self.visit_fn_args(args); + for statement in body { + self.visit_typed_statement(statement); + } + } + + fn visit_typed_pattern_variable( + &mut self, + _: &'ast ast::SrcSpan, + name: &'ast EcoString, + type_: &'ast Arc, + ) { + self.push_completion(name, type_.clone()); + } + + fn visit_typed_pattern_discard( + &mut self, + _: &'ast ast::SrcSpan, + name: &'ast EcoString, + type_: &'ast Arc, + ) { + self.push_completion(name, type_.clone()); + } + + fn visit_typed_pattern_string_prefix( + &mut self, + _: &'ast ast::SrcSpan, + _: &'ast ast::SrcSpan, + _: &'ast Option<(EcoString, ast::SrcSpan)>, + _: &'ast ast::SrcSpan, + _: &'ast EcoString, + right_side_assignment: &'ast ast::AssignName, + ) { + self.push_completion(right_side_assignment.name(), type_::string()); + } + + fn visit_typed_pattern_assign( + &mut self, + _: &'ast ast::SrcSpan, + name: &'ast EcoString, + pattern: &'ast Pattern>, + ) { + self.visit_typed_pattern(pattern); + self.push_completion(name, pattern.type_().clone()); } } diff --git a/compiler-core/src/language_server/edits.rs b/compiler-core/src/language_server/edits.rs new file mode 100644 index 000000000..b0ce6c2fe --- /dev/null +++ b/compiler-core/src/language_server/edits.rs @@ -0,0 +1,78 @@ +use ecow::EcoString; +use lsp_types::{Position, Range, TextEdit}; + +use crate::{ + ast::{Definition, Import, TypedDefinition}, + build::Module, + line_numbers::LineNumbers, +}; + +use super::src_span_to_lsp_range; + +// Gets the position of the import statement if it's the first definition in the module. +pub fn position_of_first_definition_if_import( + module: &Module, + line_numbers: &LineNumbers, +) -> Option { + // As "self.module.ast.definitions" could be sorted, let's find the actual first definition by position. + let first_definition = module + .ast + .definitions + .iter() + .min_by(|a, b| a.location().start.cmp(&b.location().start)); + let import = first_definition.and_then(get_import); + import.map(|import| src_span_to_lsp_range(import.location, line_numbers).start) +} + +pub fn get_import(statement: &TypedDefinition) -> Option<&Import> { + match statement { + Definition::Import(import) => Some(import), + _ => None, + } +} + +pub enum Newlines { + Single, + Double, +} + +// Returns how many newlines should be added after an import statement. By default `Newlines::Single`, +// but if there's not any import statement, it returns `Newlines::Double`. +// +// * ``import_location`` - The position of the first import statement in the source code. +pub fn add_newlines_after_import( + import_location: Position, + has_imports: bool, + line_numbers: &LineNumbers, + src: &str, +) -> Newlines { + let import_start_cursor = + line_numbers.byte_index(import_location.line, import_location.character); + let is_new_line = src + .chars() + .nth(import_start_cursor as usize) + .unwrap_or_default() + == '\n'; + match !has_imports && !is_new_line { + true => Newlines::Double, + false => Newlines::Single, + } +} + +pub fn get_import_edit( + import_location: Position, + module_full_name: &EcoString, + insert_newlines: &Newlines, +) -> TextEdit { + let new_lines = match insert_newlines { + Newlines::Single => "\n", + Newlines::Double => "\n\n", + }; + TextEdit { + range: Range { + start: import_location, + end: import_location, + }, + new_text: ["import ", module_full_name, new_lines].concat(), + } +} diff --git a/compiler-core/src/language_server/engine.rs b/compiler-core/src/language_server/engine.rs index 27f3caba0..2242b9432 100644 --- a/compiler-core/src/language_server/engine.rs +++ b/compiler-core/src/language_server/engine.rs @@ -1,7 +1,7 @@ use crate::{ analyse::name::correct_name_case, ast::{ - Arg, CustomType, Definition, ModuleConstant, SrcSpan, TypedExpr, TypedFunction, + CustomType, Definition, ModuleConstant, SrcSpan, TypedArg, TypedExpr, TypedFunction, TypedModule, TypedPattern, }, build::{type_constructor_from_modules, Located, Module, UnqualifiedImport}, @@ -23,14 +23,15 @@ use ecow::EcoString; use itertools::Itertools; use lsp::CodeAction; use lsp_types::{ - self as lsp, DocumentSymbol, Hover, HoverContents, MarkedString, SignatureHelp, SymbolKind, - SymbolTag, Url, + self as lsp, DocumentSymbol, Hover, HoverContents, MarkedString, Position, Range, + SignatureHelp, SymbolKind, SymbolTag, TextEdit, Url, }; use std::sync::Arc; use super::{ code_action::{ - CodeActionBuilder, FillInMissingLabelledArgs, LabelShorthandSyntax, LetAssertToCase, + code_action_add_missing_patterns, code_action_import_module, CodeActionBuilder, + FillInMissingLabelledArgs, LabelShorthandSyntax, LetAssertToCase, RedundantTupleInCaseSubject, }, completer::Completer, @@ -293,8 +294,11 @@ where return Ok(None); }; + code_action_unused_values(module, ¶ms, &mut actions); code_action_unused_imports(module, ¶ms, &mut actions); code_action_fix_names(module, ¶ms, &this.error, &mut actions); + code_action_import_module(module, ¶ms, &this.error, &mut actions); + code_action_add_missing_patterns(module, ¶ms, &this.error, &mut actions); actions.extend(LetAssertToCase::new(module, ¶ms).code_actions()); actions.extend(RedundantTupleInCaseSubject::new(module, ¶ms).code_actions()); actions.extend(LabelShorthandSyntax::new(module, ¶ms).code_actions()); @@ -487,7 +491,7 @@ where .and_then(|module| { if is_type { module.types.get(name).map(|t| { - hover_for_annotation(*location, t.typ.as_ref(), Some(t), lines) + hover_for_annotation(*location, t.type_.as_ref(), Some(t), lines) }) } else { module.values.get(name).map(|v| { @@ -783,7 +787,7 @@ fn hover_for_function_head(fun: &TypedFunction, line_numbers: LineNumbers) -> Ho } } -fn hover_for_function_argument(argument: &Arg>, line_numbers: LineNumbers) -> Hover { +fn hover_for_function_argument(argument: &TypedArg, line_numbers: LineNumbers) -> Hover { let type_ = Printer::new().pretty_print(&argument.type_, 0); let contents = format!("```gleam\n{type_}\n```"); Hover { @@ -890,7 +894,7 @@ fn hover_for_imported_value( } // Returns true if any part of either range overlaps with the other. -pub fn overlaps(a: lsp_types::Range, b: lsp_types::Range) -> bool { +pub fn overlaps(a: Range, b: Range) -> bool { position_within(a.start, b) || position_within(a.end, b) || position_within(b.start, a) @@ -898,22 +902,93 @@ pub fn overlaps(a: lsp_types::Range, b: lsp_types::Range) -> bool { } // Returns true if a range is contained within another. -pub fn within(a: lsp_types::Range, b: lsp_types::Range) -> bool { +pub fn within(a: Range, b: Range) -> bool { position_within(a.start, b) && position_within(a.end, b) } // Returns true if a position is within a range. -fn position_within(position: lsp_types::Position, range: lsp_types::Range) -> bool { +fn position_within(position: Position, range: Range) -> bool { position >= range.start && position <= range.end } +fn code_action_unused_values( + module: &Module, + params: &lsp::CodeActionParams, + actions: &mut Vec, +) { + let uri = ¶ms.text_document.uri; + let mut unused_values: Vec<&SrcSpan> = module + .ast + .type_info + .warnings + .iter() + .filter_map(|warning| match warning { + type_::Warning::ImplicitlyDiscardedResult { location } => Some(location), + _ => None, + }) + .collect(); + + if unused_values.is_empty() { + return; + } + + // Convert src spans to lsp range + let line_numbers = LineNumbers::new(&module.code); + + // Sort spans by start position, with longer spans coming first + unused_values.sort_by_key(|span| (span.start, -(span.end as i64 - span.start as i64))); + + let mut processed_lsp_range = Vec::new(); + + for unused in unused_values { + let SrcSpan { start, end } = *unused; + let hover_range = src_span_to_lsp_range(SrcSpan::new(start, end), &line_numbers); + + // Check if this span is contained within any previously processed span + if processed_lsp_range + .iter() + .any(|&prev_lsp_range| within(hover_range, prev_lsp_range)) + { + continue; + } + + // Check if the cursor is within this span + if !within(params.range, hover_range) { + continue; + } + + let edit = TextEdit { + range: src_span_to_lsp_range(SrcSpan::new(start, start), &line_numbers), + new_text: "let _ = ".into(), + }; + + CodeActionBuilder::new("Assign unused Result value to `_`") + .kind(lsp_types::CodeActionKind::QUICKFIX) + .changes(uri.clone(), vec![edit]) + .preferred(true) + .push_to(actions); + + processed_lsp_range.push(hover_range); + } +} + fn code_action_unused_imports( module: &Module, params: &lsp::CodeActionParams, actions: &mut Vec, ) { let uri = ¶ms.text_document.uri; - let unused = &module.ast.type_info.unused_imports; + let unused: Vec<&SrcSpan> = module + .ast + .type_info + .warnings + .iter() + .filter_map(|warning| match warning { + type_::Warning::UnusedImportedModuleAlias { location, .. } + | type_::Warning::UnusedImportedModule { location, .. } => Some(location), + _ => None, + }) + .collect(); if unused.is_empty() { return; @@ -939,7 +1014,7 @@ fn code_action_unused_imports( // Keep track of whether any unused import has is where the cursor is hovered = hovered || overlaps(params.range, range); - edits.push(lsp_types::TextEdit { + edits.push(TextEdit { range, new_text: "".into(), }); @@ -1004,7 +1079,7 @@ fn code_action_fix_names( let range = src_span_to_lsp_range(location, &line_numbers); // Check if the user's cursor is on the invalid name if overlaps(params.range, range) { - let edit = lsp_types::TextEdit { + let edit = TextEdit { range, new_text: correction.to_string(), }; diff --git a/compiler-core/src/language_server/progress.rs b/compiler-core/src/language_server/progress.rs index 172b48e2d..05f17befa 100644 --- a/compiler-core/src/language_server/progress.rs +++ b/compiler-core/src/language_server/progress.rs @@ -51,7 +51,7 @@ impl<'a> ConnectionProgressReporter<'a> { } } -impl<'a> ProgressReporter for ConnectionProgressReporter<'a> { +impl ProgressReporter for ConnectionProgressReporter<'_> { fn compilation_started(&self) { // Do nothing. This is only used for tests currently. // In future we could make this emit a message to the client if compilation is taking a diff --git a/compiler-core/src/language_server/router.rs b/compiler-core/src/language_server/router.rs index 6f180edf8..6350f92cf 100644 --- a/compiler-core/src/language_server/router.rs +++ b/compiler-core/src/language_server/router.rs @@ -32,7 +32,7 @@ pub(crate) struct Router { progress_reporter: Reporter, } -impl<'a, IO, Reporter> Router +impl Router where // IO to be supplied from outside of gleam-core IO: FileSystemReader @@ -42,7 +42,7 @@ where + MakeLocker + Clone, // IO to be supplied from inside of gleam-core - Reporter: ProgressReporter + Clone + 'a, + Reporter: ProgressReporter + Clone, { pub fn new(progress_reporter: Reporter, io: FileSystemProxy) -> Self { Self { diff --git a/compiler-core/src/language_server/tests.rs b/compiler-core/src/language_server/tests.rs index fdd84799e..92076e8ed 100644 --- a/compiler-core/src/language_server/tests.rs +++ b/compiler-core/src/language_server/tests.rs @@ -16,6 +16,7 @@ use ecow::EcoString; use hexpm::version::{Range, Version}; use camino::{Utf8Path, Utf8PathBuf}; +use itertools::Itertools; use lsp_types::{Position, TextDocumentIdentifier, TextDocumentPositionParams, Url}; use crate::{ @@ -392,6 +393,34 @@ impl<'a> TestProject<'a> { } } + pub fn src_from_module_url(&self, url: &Url) -> Option<&str> { + let module_name: EcoString = url + .path_segments()? + .skip_while(|segment| *segment != "src") + .skip(1) + .join("/") + .trim_end_matches(".gleam") + .into(); + + if module_name == "app" { + return Some(self.src); + } + + let find_module = |modules: &Vec<(&'a str, &'a str)>| { + modules + .iter() + .find(|(name, _)| *name == module_name) + .map(|(_, src)| *src) + }; + + find_module(&self.root_package_modules) + .or_else(|| find_module(&self.dependency_modules)) + .or_else(|| find_module(&self.test_modules)) + .or_else(|| find_module(&self.hex_modules)) + .or_else(|| find_module(&self.dev_hex_modules)) + .or_else(|| find_module(&self.indirect_hex_modules)) + } + pub fn add_module(mut self, name: &'a str, src: &'a str) -> Self { self.root_package_modules.push((name, src)); self @@ -565,7 +594,7 @@ impl<'a> TestProject<'a> { } pub fn at( - self, + &self, position: Position, executor: impl FnOnce( &mut LanguageServerEngine, diff --git a/compiler-core/src/language_server/tests/action.rs b/compiler-core/src/language_server/tests/action.rs index 667642fd8..83fe4f355 100644 --- a/compiler-core/src/language_server/tests/action.rs +++ b/compiler-core/src/language_server/tests/action.rs @@ -78,6 +78,8 @@ const REMOVE_REDUNDANT_TUPLES: &str = "Remove redundant tuples"; const CONVERT_TO_CASE: &str = "Convert to case"; const USE_LABEL_SHORTHAND_SYNTAX: &str = "Use label shorthand syntax"; const FILL_LABELS: &str = "Fill labels"; +const ASSIGN_UNUSED_RESULT: &str = "Assign unused Result value to `_`"; +const ADD_MISSING_PATTERNS: &str = "Add missing patterns"; macro_rules! assert_code_action { ($title:expr, $code:literal, $range:expr $(,)?) => { @@ -1123,6 +1125,441 @@ pub fn main() { ); } +#[test] +fn test_assign_unused_result() { + assert_code_action!( + ASSIGN_UNUSED_RESULT, + r#" +pub fn main() { + Ok(0) + Nil +} +"#, + find_position_of("Ok").select_until(find_position_of("(0)")), + ); +} + +#[test] +fn test_assign_unused_result_in_block() { + assert_code_action!( + ASSIGN_UNUSED_RESULT, + r#" +pub fn main() { + { + Ok(0) + Nil + } + Nil +} +"#, + find_position_of("Ok").select_until(find_position_of("(0)")), + ); +} + +#[test] +fn test_assign_unused_result_on_block_start() { + assert_code_action!( + ASSIGN_UNUSED_RESULT, + r#" +pub fn main() { + { + Ok(0) + Ok(0) + } + Nil +} +"#, + find_position_of("{").nth_occurrence(2).to_selection() + ); +} + +#[test] +fn test_assign_unused_result_on_block_end() { + assert_code_action!( + ASSIGN_UNUSED_RESULT, + r#" +pub fn main() { + { + Ok(0) + Ok(0) + } + Nil +} +"#, + find_position_of("}").to_selection() + ); +} + +#[test] +#[should_panic(expected = "No action with the given title")] +fn test_assign_unused_result_inside_block() { + assert_code_action!( + ASSIGN_UNUSED_RESULT, + r#" +pub fn main() { + { + Nil + Ok(1) + } +} +"#, + find_position_of("Ok").select_until(find_position_of("(1)")) + ); +} + +#[test] +fn test_assign_unused_result_only_first_action() { + assert_code_action!( + ASSIGN_UNUSED_RESULT, + r#" +pub fn main() { + Ok(0) + Ok(1) + Nil +} +"#, + find_position_of("Ok").select_until(find_position_of("(0)")) + ); +} + +#[test] +#[should_panic(expected = "No action with the given title")] +fn test_assign_unused_result_not_on_return_value() { + assert_code_action!( + ASSIGN_UNUSED_RESULT, + r#" +pub fn main() { + Ok(0) +} +"#, + find_position_of("Ok").select_until(find_position_of("(0)")) + ); +} + +#[test] +#[should_panic(expected = "No action with the given title")] +fn test_assign_unused_result_not_on_return_value_in_block() { + assert_code_action!( + ASSIGN_UNUSED_RESULT, + r#" +pub fn main() { + let _ = { + Ok(0) + } + Nil +}"#, + find_position_of("Ok").select_until(find_position_of("(0)")) + ); +} + +#[test] +fn test_import_module_from_function() { + let src = " +pub fn main() { + result.is_ok() +} +"; + + assert_code_action!( + "Import `result`", + TestProject::for_source(src).add_hex_module("result", "pub fn is_ok() {}"), + find_position_of("result").select_until(find_position_of(".")) + ); +} + +#[test] +fn test_import_path_module_from_function() { + let src = r#" +pub fn main() { + io.println("Hello, world!") +} +"#; + + assert_code_action!( + "Import `gleam/io`", + TestProject::for_source(src) + .add_hex_module("gleam/io", "pub fn println(message: String) {}"), + find_position_of("io").select_until(find_position_of(".")) + ); +} + +#[test] +fn test_import_module_from_type() { + let src = "type Wobble = wibble.Wubble"; + + assert_code_action!( + "Import `mod/wibble`", + TestProject::for_source(src).add_hex_module("mod/wibble", "pub type Wubble { Wubble }"), + find_position_of("wibble").select_until(find_position_of(".")) + ); +} + +#[test] +fn test_import_module_from_constructor() { + let src = " +pub fn main() { + let value = values.Value(10) +} +"; + + assert_code_action!( + "Import `values`", + TestProject::for_source(src).add_hex_module("values", "pub type Value { Value(Int) }"), + find_position_of("values").select_until(find_position_of(".")) + ); +} + +#[test] +fn test_rename_module_for_imported() { + let src = r#" +import gleam/io + +pub fn main() { + i.println("Hello, world!") +} +"#; + + assert_code_action!( + "Did you mean `io`", + TestProject::for_source(src) + .add_hex_module("gleam/io", "pub fn println(message: String) {}"), + find_position_of("i.").select_until(find_position_of("println")) + ); +} + +#[test] +fn test_import_similar_module() { + let src = " +pub fn main() { + reult.is_ok() +} +"; + + assert_code_action!( + "Import `result`", + TestProject::for_source(src).add_hex_module("result", "pub fn is_ok() {}"), + find_position_of("reult").select_until(find_position_of(".")) + ); +} + +#[test] +fn test_no_action_to_import_module_without_value() { + // The language server should not suggest a code action + // to import a module if it doesn't have a value with + // the same name as we are trying to access + let src = " +pub fn main() { + io.hello_world() +} +"; + + let title = "Import `io`"; + + assert_no_code_actions!( + title, + TestProject::for_source(src).add_hex_module("io", "pub fn println() {}"), + find_position_of("io").select_until(find_position_of(".")) + ); +} + +#[test] +fn test_no_action_to_import_module_without_type() { + let src = "type Name = int.String"; + + let title = "Import `int`"; + + assert_no_code_actions!( + title, + TestProject::for_source(src).add_hex_module("int", ""), + find_position_of("int").select_until(find_position_of(".")) + ); +} + +#[test] +fn test_no_action_to_import_module_with_private_value() { + // The language server should not suggest a code action + // to import a module if the value we are trying to + // access is private. + let src = " +pub fn main() { + mod.internal() +} +"; + + let title = "Import `mod`"; + + assert_no_code_actions!( + title, + TestProject::for_source(src).add_hex_module("mod", "fn internal() {}"), + find_position_of("mod").select_until(find_position_of(".")) + ); +} + +#[test] +fn test_no_action_to_import_module_with_private_type() { + let src = "type T = module.T"; + + let title = "Import `module`"; + + assert_no_code_actions!( + title, + TestProject::for_source(src).add_hex_module("module", "type T { T }"), + find_position_of("module").select_until(find_position_of(".")) + ); +} + +#[test] +fn test_no_action_to_import_module_with_constructor_named_same_as_type() { + let src = "type NotAType = shapes.Rectangle"; + + let title = "Import `shapes`"; + + assert_no_code_actions!( + title, + TestProject::for_source(src) + .add_hex_module("shapes", "pub type Shape { Rectangle, Circle }"), + find_position_of("shapes").select_until(find_position_of(".")) + ); +} + +#[test] +fn add_missing_patterns_bool() { + assert_code_action!( + ADD_MISSING_PATTERNS, + " +pub fn main() { + let bool = True + case bool {} +} +", + find_position_of("case").select_until(find_position_of("bool {")) + ); +} + +#[test] +fn add_missing_patterns_custom_type() { + assert_code_action!( + ADD_MISSING_PATTERNS, + " +type Wibble { + Wibble + Wobble + Wubble +} + +pub fn main() { + let wibble = Wobble + case wibble { + Wobble -> Nil + } +} +", + find_position_of("case").select_until(find_position_of("wibble {")) + ); +} + +#[test] +fn add_missing_patterns_tuple() { + assert_code_action!( + ADD_MISSING_PATTERNS, + " +pub fn main() { + let two_at_once = #(True, Ok(1)) + case two_at_once { + #(False, Error(_)) -> Nil + } +} +", + find_position_of("case").select_until(find_position_of("two_at_once {")) + ); +} + +#[test] +fn add_missing_patterns_list() { + assert_code_action!( + ADD_MISSING_PATTERNS, + " +pub fn main() { + let list = [1, 2, 3] + case list { + [a, b, c, 4 as d] -> d + } +} +", + find_position_of("case").select_until(find_position_of("list {")) + ); +} + +#[test] +fn add_missing_patterns_infinite() { + assert_code_action!( + ADD_MISSING_PATTERNS, + r#" +pub fn main() { + let value = 3 + case value { + 1 -> "one" + 2 -> "two" + 3 -> "three" + } +} +"#, + find_position_of("case").select_until(find_position_of("value {")) + ); +} + +#[test] +fn add_missing_patterns_multi() { + assert_code_action!( + ADD_MISSING_PATTERNS, + r#" +pub fn main() { + let a = True + let b = 1 + case a, b { + + } +} +"#, + find_position_of("case").select_until(find_position_of("b {")) + ); +} + +#[test] +fn add_missing_patterns_inline() { + // Ensure we correctly detect the indentation, if the case expression + // does not start at the beginning of the line + assert_code_action!( + ADD_MISSING_PATTERNS, + r#" +pub fn main() { + let a = True + let value = case a {} +} +"#, + find_position_of("case").select_until(find_position_of("a {")) + ); +} + +#[test] +fn import_module_from_pattern() { + let src = " +pub fn main(res) { + case res { + result.Ok(_) -> Nil + result.Error(_) -> Nil + } +} +"; + + assert_code_action!( + "Import `result`", + TestProject::for_source(src) + .add_hex_module("result", "pub type Result(v, e) { Ok(v) Error(e) }"), + find_position_of("result").select_until(find_position_of(".")) + ); +} + /* TODO: implement qualified unused location #[test] fn test_remove_unused_qualified_action() { diff --git a/compiler-core/src/language_server/tests/completion.rs b/compiler-core/src/language_server/tests/completion.rs index df560a271..ddf430931 100644 --- a/compiler-core/src/language_server/tests/completion.rs +++ b/compiler-core/src/language_server/tests/completion.rs @@ -28,9 +28,9 @@ macro_rules! assert_completion { let src = $project.src; let result = completion_with_prefix($project, ""); let output = format!( - "{}\n\n----- Completion content -----\n{:#?}", + "{}\n\n----- Completion content -----\n{}", show_complete(src, Position::new(0, 0)), - result + format_completion_results(result) ); insta::assert_snapshot!(insta::internals::AutoName, output, src); }; @@ -38,9 +38,9 @@ macro_rules! assert_completion { let src = $project.src; let result = completion($project, $position); let output = format!( - "{}\n\n----- Completion content -----\n{:#?}", + "{}\n\n----- Completion content -----\n{}", show_complete(src, $position), - result + format_completion_results(result) ); insta::assert_snapshot!(insta::internals::AutoName, output, src); }; @@ -53,14 +53,110 @@ macro_rules! assert_completion_with_prefix { let result = completion_with_prefix($project, $prefix); let line = 1 + $prefix.lines().count(); let output = format!( - "{}\n\n----- Completion content -----\n{:#?}", + "{}\n\n----- Completion content -----\n{}", show_complete(src, Position::new(line as u32, 0)), - result + format_completion_results(result) ); insta::assert_snapshot!(insta::internals::AutoName, output, src); }; } +fn format_completion_results(completions: Vec) -> EcoString { + use std::fmt::Write; + let mut buffer: EcoString = "".into(); + + for CompletionItem { + label, + label_details, + kind, + detail, + documentation, + deprecated, + preselect, + sort_text, + filter_text, + insert_text, + insert_text_format, + insert_text_mode, + text_edit, + additional_text_edits, + command, + commit_characters, + data, + tags, + } in completions + { + assert!(deprecated.is_none()); + assert!(preselect.is_none()); + assert!(filter_text.is_none()); + assert!(insert_text.is_none()); + assert!(insert_text_format.is_none()); + assert!(insert_text_mode.is_none()); + assert!(command.is_none()); + assert!(commit_characters.is_none()); + assert!(data.is_none()); + assert!(tags.is_none()); + + buffer.push_str(&label); + + if let Some(kind) = kind { + write!(buffer, "\n kind: {:?}", kind).unwrap(); + } + + if let Some(detail) = detail { + write!(buffer, "\n detail: {}", detail).unwrap(); + } + + if let Some(sort_text) = sort_text { + write!(buffer, "\n sort: {}", sort_text).unwrap(); + } + + if let Some(label_details) = label_details { + assert!(label_details.detail.is_none()); + if let Some(desc) = label_details.description { + write!(buffer, "\n desc: {}", desc).unwrap(); + } + } + + if let Some(documentation) = documentation { + let lsp_types::Documentation::MarkupContent(m) = documentation else { + panic!("unexpected docs in test {:?}", documentation); + }; + match m.kind { + lsp_types::MarkupKind::Markdown => (), + lsp_types::MarkupKind::PlainText => { + panic!("unexpected docs markup kind {:?}", m.kind) + } + }; + write!(buffer, "\n docs: {:?}", m.value).unwrap(); + } + + let edit = |buffer: &mut EcoString, e: lsp_types::TextEdit| { + let a = e.range.start.line; + let b = e.range.start.character; + let c = e.range.start.line; + let d = e.range.start.character; + write!(buffer, "\n [{a}:{b}-{c}:{d}]: {:?}", e.new_text).unwrap(); + }; + + if let Some(text_edit) = text_edit { + let lsp_types::CompletionTextEdit::Edit(e) = text_edit else { + panic!("unexpected text edit in test {:?}", text_edit); + }; + buffer.push_str("\n edits:"); + edit(&mut buffer, e); + } + + for e in additional_text_edits.unwrap_or_default() { + edit(&mut buffer, e); + } + + buffer.push('\n'); + } + + buffer +} + fn completion(tester: TestProject<'_>, position: Position) -> Vec { tester.at(position, |engine, param, src| { let response = engine.completion(param, src); @@ -712,6 +808,231 @@ pub fn wibble( assert_completion!(TestProject::for_source(code), Position::new(4, 0)); } +#[test] +fn local_variable() { + let code = " +pub fn main(wibble: Int) { + let wobble = 1 + w + + let wabble = 2 +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(3, 3)); +} + +#[test] +fn local_variable_anonymous_function() { + let code = " +pub fn main() { + let add_one = fn(wibble: Int) { wibble + 1 } + add_one(1) +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(2, 40)); +} + +#[test] +fn local_variable_nested_anonymous_function() { + let code = " +pub fn main() { + let add_one = fn(wibble: Int) { + let wabble = 1 + let add_two = fn(wobble: Int) { wobble + 2 } + wibble + add_two(1) + } + add_one(1) +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(4, 42)); +} + +#[test] +fn local_variable_ignore_anonymous_function_args() { + let code = " +pub fn main() { + let add_one = fn(wibble: Int) { wibble + 1 } + let wobble = 1 + w +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(4, 3)); +} + +#[test] +fn local_variable_ignore_anonymous_function_args_nested() { + let code = " +pub fn main() { + let add_one = fn(wibble: Int) { + let wabble = 1 + let add_two = fn(wobble: Int) { wobble + 2 } + wibble + add_two(1) + } + add_one(1) +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(5, 10)); +} + +#[test] +fn local_variable_ignore_anonymous_function_returned() { + let code = " +pub fn main() { + fn(wibble: Int) { + let wabble = 1 + let add_two = fn(wobble: Int) { wobble + 2 } + wibble + add_two(1) + } +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(5, 10)); +} + +#[test] +fn local_variable_case_expression() { + let code = " +pub fn main() { + case True { + True as wibble -> { todo } + False -> { todo } + } +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(3, 25)); +} + +#[test] +fn local_variable_inside_nested_exprs() { + let code = r#" +type Foo { Bar(List(#(Bool))) } +fn wibble() { + Bar([#(!{ + let foo = True + foo + })]) + todo +} +"#; + + assert_completion!(TestProject::for_source(code), Position::new(5, 7)); +} + +#[test] +fn local_variable_pipe() { + let code = " +pub fn main() { + let add_one = fn(wibble: Int) { wibble + 1 } + let wobble = 1 + wobble |> add_one +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(4, 19)); +} + +#[test] +fn local_variable_pipe_with_args() { + let code = " +pub fn main() { + let add_one = fn(wibble: Int, wobble: Int) { wibble + wobble } + let wobble = 1 + let wibble = 2 + wobble |> add_one(1, wibble) +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(5, 29)); +} + +#[test] +fn local_variable_function_call() { + let code = " +fn add_one(wibble: Int) -> Int { + wibble + 1 +} + +pub fn main() { + let wobble = 1 + add_one(wobble) +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(7, 16)); +} + +#[test] +fn local_variable_ignored() { + let code = " +fn wibble() { + let a = 1 + let _b = 2 + +} +"; + assert_completion!(TestProject::for_source(code), Position::new(4, 0)); +} + +#[test] +fn local_variable_as() { + let code = " +fn wibble() { + let b as c = 5 + +} +"; + assert_completion!(TestProject::for_source(code), Position::new(3, 0)); +} + +#[test] +fn local_variable_tuple() { + let code = " +fn wibble() { + let assert #([d, e] as f, g) = #([0, 1], 2) + +} +"; + assert_completion!(TestProject::for_source(code), Position::new(3, 0)); +} + +#[test] +fn local_variable_bit_array() { + let code = " +fn wibble() { + let assert <> as i = <<1:1>> + +} +"; + assert_completion!(TestProject::for_source(code), Position::new(3, 0)); +} + +#[test] +fn local_variable_string() { + let code = r#" +fn wibble() { + let assert "a" <> j = "ab" + +} +"#; + assert_completion!(TestProject::for_source(code), Position::new(3, 0)); +} + +#[test] +fn local_variable_ignore_within_function() { + let code = " +fn main(a, b, z) { + Nil +} +"; + assert_completion!(TestProject::for_source(code), Position::new(1, 14)); +} + #[test] fn internal_values_from_root_package_are_in_the_completions() { let dep = r#" @@ -1383,3 +1704,52 @@ fn fun() { ); assert_eq!(completions, vec![],); } + +#[test] +fn completions_for_prelude_values() { + let code = " +pub fn main() { + let my_bool = T +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(2, 17)); +} + +#[test] +fn variable_shadowing() { + let code = " +pub fn main() { + let x = 1 + let x = [1, 2] + +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(4, 0)); +} + +#[test] +fn argument_shadowing() { + let code = " +pub fn main(x: Int) { + fn(x: Float) { + + } +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(3, 0)); +} + +#[test] +fn argument_variable_shadowing() { + let code = " +pub fn main(x: Int) { + let x = [1, 2] + +} +"; + + assert_completion!(TestProject::for_source(code), Position::new(3, 0)); +} diff --git a/compiler-core/src/language_server/tests/definition.rs b/compiler-core/src/language_server/tests/definition.rs index 26c569d28..42dfba05d 100644 --- a/compiler-core/src/language_server/tests/definition.rs +++ b/compiler-core/src/language_server/tests/definition.rs @@ -2,7 +2,7 @@ use lsp_types::{GotoDefinitionParams, Location, Position, Range, Url}; use super::*; -fn definition(tester: TestProject<'_>, position: Position) -> Option { +fn definition(tester: &TestProject<'_>, position: Position) -> Option { tester.at(position, |engine, param, _| { let params = GotoDefinitionParams { text_document_position_params: param, @@ -15,106 +15,99 @@ fn definition(tester: TestProject<'_>, position: Position) -> Option { }) } +fn pretty_definition(project: TestProject<'_>, position_finder: PositionFinder) -> String { + let position = position_finder.find_position(project.src); + let location = definition(&project, position).expect("a location to jump to"); + let pretty_destination = location + .uri + .path_segments() + .expect("a location to jump to") + // To make snapshots the same both on windows and unix systems we need + // to discard windows' `C:` path segment at the beginning of a uri. + .skip_while(|segment| *segment == "C:") + .join("/"); + + let src = hover::show_hover( + project.src, + Range { + start: position, + end: position, + }, + position, + ); + + let destination = hover::show_hover( + project + .src_from_module_url(&location.uri) + .expect("a module to jump to"), + location.range, + location.range.start, + ); + + format!( + "----- Jumping from `src/app.gleam` +{src} +----- Jumped to `{pretty_destination}` +{destination}", + ) +} + +#[macro_export] +macro_rules! assert_goto { + ($src:literal, $position:expr) => { + let project = TestProject::for_source($src); + assert_goto!(project, $position); + }; + ($project:expr, $position:expr) => { + let output = pretty_definition($project, $position); + insta::assert_snapshot!(insta::internals::AutoName, output); + }; +} + #[test] fn goto_definition_local_variable() { - let code = " + assert_goto!( + " pub fn main() { let x = 1 x -}"; - - assert_eq!( - definition(TestProject::for_source(code), Position::new(3, 2)), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 2, - character: 6 - }, - end: Position { - line: 2, - character: 7 - } - } - }) - ) +}", + find_position_of("x").nth_occurrence(2) + ); } #[test] fn goto_definition_same_module_constants() { - let code = " + assert_goto!( + " const x = 1 pub fn main() { x -}"; - - assert_eq!( - definition(TestProject::for_source(code), Position::new(4, 2)), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 7 - } - } - }) - ) +}", + find_position_of("x").nth_occurrence(2) + ); } #[test] fn goto_definition_same_module_functions() { - let code = " + assert_goto!( + " fn add_2(x) { x + 2 } pub fn main() { add_2(1) -}"; - - assert_eq!( - definition(TestProject::for_source(code), Position::new(6, 3)), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 11 - } - } - }) - ) +}", + find_position_of("add_2(1)") + ); } #[test] fn goto_definition_same_module_records() { - let code = " + assert_goto!( + " pub type Rec { Var1(Int) Var2(Int, Int) @@ -123,29 +116,9 @@ pub type Rec { pub fn main() { let a = Var1(1) let b = Var2(2, 3) -}"; - - assert_eq!( - definition(TestProject::for_source(code), Position::new(7, 11)), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 2, - character: 2 - }, - end: Position { - line: 2, - character: 11 - } - } - }) - ) +}", + find_position_of("Var1(1)") + ); } #[test] @@ -157,30 +130,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), - Position::new(3, 19) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 16 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), + find_position_of("my_num") + ); } #[test] @@ -192,30 +145,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), - Position::new(3, 3) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 16 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), + find_position_of("my_num").nth_occurrence(2) + ); } #[test] @@ -227,30 +160,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub fn my_fn() { Nil }"), - Position::new(3, 19) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 14 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub fn my_fn() { Nil }"), + find_position_of("my_fn") + ); } #[test] @@ -268,30 +181,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", dep_src), - Position::new(3, 20) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 2, - character: 2 - }, - end: Position { - line: 2, - character: 11 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", dep_src), + find_position_of("Var1(1)") + ); } #[test] @@ -309,30 +202,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", dep_src), - Position::new(3, 3) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 2, - character: 2 - }, - end: Position { - line: 2, - character: 11 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", dep_src), + find_position_of("Var1(1)").under_char('a') + ); } #[test] @@ -344,30 +217,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_hex_module("example_module", "pub const my_num = 1"), - Position::new(3, 20) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\build\packages\hex\src\example_module.gleam" - } else { - "/build/packages/hex/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 16 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_hex_module("example_module", "pub const my_num = 1"), + find_position_of("my_num").under_char('u') + ); } #[test] @@ -379,31 +232,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code) - .add_hex_module("example_module", "pub fn my_fn() { Nil }"), - Position::new(3, 20) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\build\packages\hex\src\example_module.gleam" - } else { - "/build/packages/hex/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 14 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_hex_module("example_module", "pub fn my_fn() { Nil }"), + find_position_of("my_fn") + ); } #[test] @@ -571,30 +403,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_hex_module("example_module", hex_src), - Position::new(3, 20) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\build\packages\hex\src\example_module.gleam" - } else { - "/build/packages/hex/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 2, - character: 2 - }, - end: Position { - line: 2, - character: 11 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_hex_module("example_module", hex_src), + find_position_of("Var1(1)").under_char('r') + ); } #[test] @@ -606,36 +418,16 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code) - .add_dep_module("example_module", "pub fn my_fn() { Nil }"), - Position::new(3, 20) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\dep\src\example_module.gleam" - } else { - "/dep/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 14 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_dep_module("example_module", "pub fn my_fn() { Nil }"), + find_position_of("my_fn").under_char('y') + ); } #[test] fn goto_definition_type() { - let code = " + assert_goto!( + " pub type Rec { Var1(Int) Var2(Int, Int) @@ -643,29 +435,9 @@ pub type Rec { pub fn make_var() -> Rec { Var1(1) -}"; - - assert_eq!( - definition(TestProject::for_source(code), Position::new(6, 22)), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 12 - } - } - }) - ) +}", + find_position_of("Rec").nth_occurrence(2) + ); } #[test] @@ -684,30 +456,10 @@ fn make_var() -> example_module.Rec { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_hex_module("example_module", hex_src), - Position::new(2, 33) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\build\packages\hex\src\example_module.gleam" - } else { - "/build/packages/hex/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 12 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_hex_module("example_module", hex_src), + find_position_of("Rec") + ); } #[test] @@ -726,30 +478,10 @@ fn make_var() -> example_module.Rec { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_dep_module("example_module", dep), - Position::new(2, 33) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\dep\src\example_module.gleam" - } else { - "/dep/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 12 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_dep_module("example_module", dep), + find_position_of("Rec") + ); } #[test] @@ -775,30 +507,10 @@ fn make_var() -> example_module.Wabble(example_module.Wibble(example_module.Wobb } "; - assert_eq!( - definition( - TestProject::for_source(code).add_hex_module("example_module", hex_src), - Position::new(2, 80) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\build\packages\hex\src\example_module.gleam" - } else { - "/build/packages/hex/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 15 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_hex_module("example_module", hex_src), + find_position_of("Wobble").under_char('o') + ); } #[test] @@ -810,30 +522,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), - Position::new(1, 13) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 0 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), + find_position_of("example_module").under_char('p') + ); } #[test] @@ -845,30 +537,12 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), - Position::new(1, 29) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 0 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), + find_position_of("example") + .nth_occurrence(2) + .under_char('x') + ); } #[test] @@ -880,30 +554,25 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), - Position::new(1, 26) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 16 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), + find_position_of("my_num").under_char('_') + ); +} + +#[test] +fn goto_definition_unqualified_function() { + let code = " +import wibble.{wobble} +fn main() { + wobble() +} +"; + + assert_goto!( + TestProject::for_source(code).add_module("wibble", "pub fn wobble() {}"), + find_position_of("wobble").nth_occurrence(2).under_char('o') + ); } #[test] @@ -915,28 +584,28 @@ fn main() -> MyType { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub type MyType = Int"), - Position::new(1, 33) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 21 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub type MyType = Int"), + find_position_of("MyType").under_char('T') + ); +} + +// https://github.com/gleam-lang/gleam/issues/3610 +#[test] +fn goto_definition_of_external_function_in_same_module() { + let code = " +@external(erlang, \"wibble\", \"wobble\") +fn external_function() -> Nil + +fn main() { + external_function() +} +"; + + assert_goto!( + TestProject::for_source(code), + find_position_of("external_function") + .nth_occurrence(2) + .under_char('l') + ); } diff --git a/compiler-core/src/language_server/tests/signature_help.rs b/compiler-core/src/language_server/tests/signature_help.rs index 48f2733d7..8acf6b79e 100644 --- a/compiler-core/src/language_server/tests/signature_help.rs +++ b/compiler-core/src/language_server/tests/signature_help.rs @@ -38,23 +38,19 @@ fn pretty_signature_help(signature_help: SignatureHelp) -> String { let documentation = match documentation { Some(d) => format!("Documentation:\n{:#?}", d), - None => format!("No documentation"), + None => "No documentation".to_string(), }; let label = match active_parameter { - None => format!("{label}"), + None => label.to_string(), Some(i) => match parameters.get(i as usize) { - None => format!("{label}"), + None => label.to_string(), Some(ParameterInformation { label: ParameterLabel::LabelOffsets([start, end]), .. }) => { - let spaces = std::iter::repeat(' ') - .take(*start as usize) - .collect::(); - let underlined = std::iter::repeat('▔') - .take((end - start) as usize) - .collect::(); + let spaces = " ".repeat(*start as usize); + let underlined = "▔".repeat((end - start) as usize); format!("{label}\n{spaces}{underlined}") } Some(_) => panic!("unexpected response"), diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_bool.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_bool.snap new file mode 100644 index 000000000..f2aaad557 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_bool.snap @@ -0,0 +1,22 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n let bool = True\n case bool {}\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + let bool = True + case bool {} + ▔▔▔▔▔↑ +} + + +----- AFTER ACTION + +pub fn main() { + let bool = True + case bool { + False -> todo + True -> todo + } +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_custom_type.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_custom_type.snap new file mode 100644 index 000000000..e4695b147 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_custom_type.snap @@ -0,0 +1,37 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\ntype Wibble {\n Wibble\n Wobble\n Wubble\n}\n\npub fn main() {\n let wibble = Wobble\n case wibble {\n Wobble -> Nil\n }\n}\n" +--- +----- BEFORE ACTION + +type Wibble { + Wibble + Wobble + Wubble +} + +pub fn main() { + let wibble = Wobble + case wibble { + ▔▔▔▔▔↑ + Wobble -> Nil + } +} + + +----- AFTER ACTION + +type Wibble { + Wibble + Wobble + Wubble +} + +pub fn main() { + let wibble = Wobble + case wibble { + Wobble -> Nil + Wibble -> todo + Wubble -> todo + } +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_infinite.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_infinite.snap new file mode 100644 index 000000000..6d4e9d76c --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_infinite.snap @@ -0,0 +1,28 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n let value = 3\n case value {\n 1 -> \"one\"\n 2 -> \"two\"\n 3 -> \"three\"\n }\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + let value = 3 + case value { + ▔▔▔▔▔↑ + 1 -> "one" + 2 -> "two" + 3 -> "three" + } +} + + +----- AFTER ACTION + +pub fn main() { + let value = 3 + case value { + 1 -> "one" + 2 -> "two" + 3 -> "three" + _ -> todo + } +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_inline.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_inline.snap new file mode 100644 index 000000000..e435df9b2 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_inline.snap @@ -0,0 +1,22 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n let a = True\n let value = case a {}\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + let a = True + let value = case a {} + ▔▔▔▔▔↑ +} + + +----- AFTER ACTION + +pub fn main() { + let a = True + let value = case a { + False -> todo + True -> todo + } +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_list.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_list.snap new file mode 100644 index 000000000..e682bff23 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_list.snap @@ -0,0 +1,29 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n let list = [1, 2, 3]\n case list {\n [a, b, c, 4 as d] -> d\n }\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + let list = [1, 2, 3] + case list { + ▔▔▔▔▔↑ + [a, b, c, 4 as d] -> d + } +} + + +----- AFTER ACTION + +pub fn main() { + let list = [1, 2, 3] + case list { + [a, b, c, 4 as d] -> d + [] -> todo + [_, _, _, _, _, ..] -> todo + [_, _, _, _] -> todo + [_, _, _] -> todo + [_, _] -> todo + [_] -> todo + } +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_multi.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_multi.snap new file mode 100644 index 000000000..53a508ae4 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_multi.snap @@ -0,0 +1,26 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n let a = True\n let b = 1\n case a, b {\n\n }\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + let a = True + let b = 1 + case a, b { + ▔▔▔▔▔▔▔▔↑ + + } +} + + +----- AFTER ACTION + +pub fn main() { + let a = True + let b = 1 + case a, b { + False, _ -> todo + True, _ -> todo + } +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_tuple.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_tuple.snap new file mode 100644 index 000000000..6076ecda5 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__add_missing_patterns_tuple.snap @@ -0,0 +1,25 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n let two_at_once = #(True, Ok(1))\n case two_at_once {\n #(False, Error(_)) -> Nil\n }\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + let two_at_once = #(True, Ok(1)) + case two_at_once { + ▔▔▔▔▔↑ + #(False, Error(_)) -> Nil + } +} + + +----- AFTER ACTION + +pub fn main() { + let two_at_once = #(True, Ok(1)) + case two_at_once { + #(False, Error(_)) -> Nil + #(True, Error(_)) -> todo + #(_, Ok(_)) -> todo + } +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result.snap new file mode 100644 index 000000000..d98b8bf7f --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n Ok(0)\n Nil\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + Ok(0) + ▔▔↑ + Nil +} + + +----- AFTER ACTION + +pub fn main() { + let _ = Ok(0) + Nil +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_in_block.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_in_block.snap new file mode 100644 index 000000000..53c5314c1 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_in_block.snap @@ -0,0 +1,25 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n {\n Ok(0)\n Nil\n }\n Nil\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + { + Ok(0) + ▔▔↑ + Nil + } + Nil +} + + +----- AFTER ACTION + +pub fn main() { + { + let _ = Ok(0) + Nil + } + Nil +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_on_block_end.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_on_block_end.snap new file mode 100644 index 000000000..a59263b31 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_on_block_end.snap @@ -0,0 +1,25 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n {\n Ok(0)\n Ok(0)\n }\n Nil\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + { + Ok(0) + Ok(0) + } + ↑ + Nil +} + + +----- AFTER ACTION + +pub fn main() { + let _ = { + Ok(0) + Ok(0) + } + Nil +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_on_block_start.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_on_block_start.snap new file mode 100644 index 000000000..e878ab1c5 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_on_block_start.snap @@ -0,0 +1,25 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n {\n Ok(0)\n Ok(0)\n }\n Nil\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + { + ↑ + Ok(0) + Ok(0) + } + Nil +} + + +----- AFTER ACTION + +pub fn main() { + let _ = { + Ok(0) + Ok(0) + } + Nil +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_only_first_action.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_only_first_action.snap new file mode 100644 index 000000000..3ef4d3ed9 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__assign_unused_result_only_first_action.snap @@ -0,0 +1,21 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n Ok(0)\n Ok(1)\n Nil\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + Ok(0) + ▔▔↑ + Ok(1) + Nil +} + + +----- AFTER ACTION + +pub fn main() { + let _ = Ok(0) + Ok(1) + Nil +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_constructor.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_constructor.snap new file mode 100644 index 000000000..bf1d37342 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_constructor.snap @@ -0,0 +1,18 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n let value = values.Value(10)\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + let value = values.Value(10) + ▔▔▔▔▔▔↑ +} + + +----- AFTER ACTION +import values + +pub fn main() { + let value = values.Value(10) +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_function.snap new file mode 100644 index 000000000..3dbed4971 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_function.snap @@ -0,0 +1,18 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n result.is_ok()\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + result.is_ok() + ▔▔▔▔▔▔↑ +} + + +----- AFTER ACTION +import result + +pub fn main() { + result.is_ok() +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_pattern.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_pattern.snap new file mode 100644 index 000000000..775d04de9 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_pattern.snap @@ -0,0 +1,24 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main(res) {\n case res {\n result.Ok(_) -> Nil\n result.Error(_) -> Nil\n }\n}\n" +--- +----- BEFORE ACTION + +pub fn main(res) { + case res { + result.Ok(_) -> Nil + ▔▔▔▔▔▔↑ + result.Error(_) -> Nil + } +} + + +----- AFTER ACTION +import result + +pub fn main(res) { + case res { + result.Ok(_) -> Nil + result.Error(_) -> Nil + } +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_type.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_type.snap new file mode 100644 index 000000000..530f6ed1e --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_module_from_type.snap @@ -0,0 +1,13 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: type Wobble = wibble.Wubble +--- +----- BEFORE ACTION +type Wobble = wibble.Wubble + ▔▔▔▔▔▔↑ + + +----- AFTER ACTION +import mod/wibble + +type Wobble = wibble.Wubble diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_path_module.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_path_module.snap new file mode 100644 index 000000000..0fe7b8acd --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_path_module.snap @@ -0,0 +1,9 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "apply_first_code_action(r#\"pub fn main() {\n io.println(\"Hello, world!\")\n}\"#,\n 1)" +--- +import gleam/io + +pub fn main() { + io.println("Hello, world!") +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_path_module_from_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_path_module_from_function.snap new file mode 100644 index 000000000..0cba7cb9e --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_path_module_from_function.snap @@ -0,0 +1,18 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n io.println(\"Hello, world!\")\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + io.println("Hello, world!") + ▔▔↑ +} + + +----- AFTER ACTION +import gleam/io + +pub fn main() { + io.println("Hello, world!") +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_similar_module.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_similar_module.snap new file mode 100644 index 000000000..8ee4ffae5 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__import_similar_module.snap @@ -0,0 +1,18 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\npub fn main() {\n reult.is_ok()\n}\n" +--- +----- BEFORE ACTION + +pub fn main() { + reult.is_ok() + ▔▔▔▔▔↑ +} + + +----- AFTER ACTION +import result + +pub fn main() { + result.is_ok() +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__rename_module_for_imported.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__rename_module_for_imported.snap new file mode 100644 index 000000000..8a7398124 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__action__rename_module_for_imported.snap @@ -0,0 +1,21 @@ +--- +source: compiler-core/src/language_server/tests/action.rs +expression: "\nimport gleam/io\n\npub fn main() {\n i.println(\"Hello, world!\")\n}\n" +--- +----- BEFORE ACTION + +import gleam/io + +pub fn main() { + i.println("Hello, world!") + ▔▔↑ +} + + +----- AFTER ACTION + +import gleam/io + +pub fn main() { + io.println("Hello, world!") +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__argument_shadowing.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__argument_shadowing.snap new file mode 100644 index 000000000..800aed388 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__argument_shadowing.snap @@ -0,0 +1,48 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1742 +expression: "\npub fn main(x: Int) {\n fn(x: Float) {\n\n }\n}\n" +--- +pub fn main(x: Int) { + fn(x: Float) { +| + } +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +main + kind: Function + detail: fn(Int) -> fn(Float) -> a + sort: 2_main + desc: app + edits: + [3:0-3:0]: "main" +x + kind: Variable + detail: Float + sort: 2_x + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "x" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__argument_variable_shadowing.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__argument_variable_shadowing.snap new file mode 100644 index 000000000..2c5dea78a --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__argument_variable_shadowing.snap @@ -0,0 +1,47 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1754 +expression: "\npub fn main(x: Int) {\n let x = [1, 2]\n\n}\n" +--- +pub fn main(x: Int) { + let x = [1, 2] +| +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +main + kind: Function + detail: fn(Int) -> List(Int) + sort: 2_main + desc: app + edits: + [3:0-3:0]: "main" +x + kind: Variable + detail: List(Int) + sort: 2_x + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "x" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_const_annotation.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_const_annotation.snap index 827b000f0..ab47aa343 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_const_annotation.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_const_annotation.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1243 expression: "\n\nconst wibble: Int = 7\n\npub fn main() {\n let wibble: Int = 7\n}\n" --- const wibble: In|t = 7 @@ -10,239 +11,39 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_function_arg_annotation.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_function_arg_annotation.snap index a1cf54daa..f7f31f41e 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_function_arg_annotation.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_function_arg_annotation.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1205 expression: "\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}\n" --- pub fn wibble( @@ -10,239 +11,39 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_function_return_annotation.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_function_return_annotation.snap index e779a0ca4..a9858c0ae 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_function_return_annotation.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_function_return_annotation.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1218 expression: "\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}\n" --- pub fn wibble( @@ -10,239 +11,39 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_var_annotation.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_var_annotation.snap index ead079ca9..0af6ce030 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_var_annotation.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_a_var_annotation.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1229 expression: "\npub fn main() {\n let wibble: Int = 7\n}\n" --- pub fn main() { @@ -8,239 +9,39 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import.snap index 6712ff445..799f4c671 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 912 expression: "import dep\n\npub fn main() {\n 0\n}" --- import dep| @@ -10,43 +11,7 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "gleam", - label_details: None, - kind: Some( - Module, - ), - detail: None, - documentation: None, - deprecated: None, - preselect: None, - sort_text: None, - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 0, - character: 7, - }, - end: Position { - line: 0, - character: 10, - }, - }, - new_text: "gleam", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +gleam + kind: Module + edits: + [0:7-0:7]: "gleam" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_from_dependency.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_from_dependency.snap index e67507373..deb0915ec 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_from_dependency.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_from_dependency.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1000 expression: "import gleam\n\npub fn main() {\n 0\n}" --- import gle|am @@ -10,43 +11,7 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "example_module", - label_details: None, - kind: Some( - Module, - ), - detail: None, - documentation: None, - deprecated: None, - preselect: None, - sort_text: None, - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 0, - character: 7, - }, - end: Position { - line: 0, - character: 12, - }, - }, - new_text: "example_module", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +example_module + kind: Module + edits: + [0:7-0:7]: "example_module" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_from_dependency_with_docs.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_from_dependency_with_docs.snap index 05422bf30..7ecac8066 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_from_dependency_with_docs.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_from_dependency_with_docs.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1085 expression: "//// Main package\n//// documentation!\n\nimport gleam\n\npub fn main() {\n 0\n}" --- //// Main package @@ -13,43 +14,7 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "example_module", - label_details: None, - kind: Some( - Module, - ), - detail: None, - documentation: None, - deprecated: None, - preselect: None, - sort_text: None, - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 7, - }, - end: Position { - line: 3, - character: 12, - }, - }, - new_text: "example_module", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +example_module + kind: Module + edits: + [3:7-3:7]: "example_module" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_no_test.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_no_test.snap index 78460657d..9bb9b6717 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_no_test.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_no_test.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 886 expression: "import gleam\n\npub fn main() {\n 0\n}" --- import gle|am @@ -10,4 +11,3 @@ pub fn main() { ----- Completion content ----- -[] diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_not_from_dev_dependency.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_not_from_dev_dependency.snap index e67507373..59bd42840 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_not_from_dev_dependency.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_not_from_dev_dependency.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1032 expression: "import gleam\n\npub fn main() {\n 0\n}" --- import gle|am @@ -10,43 +11,7 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "example_module", - label_details: None, - kind: Some( - Module, - ), - detail: None, - documentation: None, - deprecated: None, - preselect: None, - sort_text: None, - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 0, - character: 7, - }, - end: Position { - line: 0, - character: 12, - }, - }, - new_text: "example_module", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +example_module + kind: Module + edits: + [0:7-0:7]: "example_module" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_not_from_indirect_dependency.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_not_from_indirect_dependency.snap index e67507373..d261b3ac7 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_not_from_indirect_dependency.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_not_from_indirect_dependency.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1015 expression: "import gleam\n\npub fn main() {\n 0\n}" --- import gle|am @@ -10,43 +11,7 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "example_module", - label_details: None, - kind: Some( - Module, - ), - detail: None, - documentation: None, - deprecated: None, - preselect: None, - sort_text: None, - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 0, - character: 7, - }, - end: Position { - line: 0, - character: 12, - }, - }, - new_text: "example_module", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +example_module + kind: Module + edits: + [0:7-0:7]: "example_module" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_preceeding_whitespace.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_preceeding_whitespace.snap index 96f6d5954..06d5b5d0b 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_preceeding_whitespace.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_preceeding_whitespace.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1115 expression: " import gleam\n\npub fn main() {\n 0\n}" --- i|mport gleam @@ -10,43 +11,7 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "dep", - label_details: None, - kind: Some( - Module, - ), - detail: None, - documentation: None, - deprecated: None, - preselect: None, - sort_text: None, - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 0, - character: 7, - }, - end: Position { - line: 0, - character: 13, - }, - }, - new_text: "dep", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +dep + kind: Module + edits: + [0:7-0:7]: "dep" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_start.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_start.snap index c336073a5..188a04cd4 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_start.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_start.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1100 expression: "import gleam\n\npub fn main() {\n 0\n}" --- |import gleam @@ -10,43 +11,7 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "dep", - label_details: None, - kind: Some( - Module, - ), - detail: None, - documentation: None, - deprecated: None, - preselect: None, - sort_text: None, - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 0, - character: 7, - }, - end: Position { - line: 0, - character: 12, - }, - }, - new_text: "dep", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +dep + kind: Module + edits: + [0:7-0:7]: "dep" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_with_docs.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_with_docs.snap index 5ff650930..826394b9b 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_with_docs.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_import_with_docs.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 985 expression: "import gleam\n\npub fn main() {\n 0\n}" --- import gle|am @@ -10,43 +11,7 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "dep", - label_details: None, - kind: Some( - Module, - ), - detail: None, - documentation: None, - deprecated: None, - preselect: None, - sort_text: None, - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 0, - character: 7, - }, - end: Position { - line: 0, - character: 12, - }, - }, - new_text: "dep", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +dep + kind: Module + edits: + [0:7-0:7]: "dep" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import.snap index e4e601fd7..515499b8e 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1160 expression: "\nimport dep.{}\n\npub fn main() {\n 0\n}" --- import dep.{|} @@ -10,194 +11,30 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "Wibble", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_Wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 12, - }, - end: Position { - line: 1, - character: 12, - }, - }, - new_text: "type Wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "myfun", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_myfun", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 12, - }, - end: Position { - line: 1, - character: 12, - }, - }, - new_text: "myfun", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wabble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Constant, - ), - detail: Some( - "String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_wabble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 12, - }, - end: Position { - line: 1, - character: 12, - }, - }, - new_text: "wabble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wibble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Constant, - ), - detail: Some( - "String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 12, - }, - end: Position { - line: 1, - character: 12, - }, - }, - new_text: "wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Wibble + kind: Class + detail: Type + sort: 3_Wibble + edits: + [1:12-1:12]: "type Wibble" +myfun + kind: Function + detail: fn() -> Int + sort: 3_myfun + desc: dep + edits: + [1:12-1:12]: "myfun" +wabble + kind: Constant + detail: String + sort: 3_wabble + desc: dep + edits: + [1:12-1:12]: "wabble" +wibble + kind: Constant + detail: String + sort: 3_wibble + desc: dep + edits: + [1:12-1:12]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import_already_imported.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import_already_imported.snap index f63175eba..0df049fc8 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import_already_imported.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import_already_imported.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1215 expression: "\nimport dep.{wibble,wabble,type Wibble}\n\npub fn main() {\n 0\n}" --- import dep.{|wibble,wabble,type Wibble} @@ -10,54 +11,10 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "myfun", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_myfun", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 12, - }, - end: Position { - line: 1, - character: 18, - }, - }, - new_text: "myfun", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +myfun + kind: Function + detail: fn() -> Int + sort: 3_myfun + desc: dep + edits: + [1:12-1:12]: "myfun" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import_on_new_line.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import_on_new_line.snap index 656ccba76..618228191 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import_on_new_line.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_an_unqualified_import_on_new_line.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1186 expression: "\nimport dep.{\n wibble,\n\n}\n\npub fn main() {\n 0\n}" --- import dep.{ @@ -13,96 +14,16 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "Wibble", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_Wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "type Wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "myfun", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_myfun", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "myfun", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Wibble + kind: Class + detail: Type + sort: 3_Wibble + edits: + [3:0-3:0]: "type Wibble" +myfun + kind: Function + detail: fn() -> Int + sort: 3_myfun + desc: dep + edits: + [3:0-3:0]: "myfun" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_function_labels.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_function_labels.snap index cb51be82b..c513a8742 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_function_labels.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_function_labels.snap @@ -12,155 +12,45 @@ fn fun() { // completion inside parens below includes labels ----- Completion content ----- -[ - CompletionItem { - label: "fun", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_fun", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 6, - character: 22, - }, - end: Position { - line: 6, - character: 22, - }, - }, - new_text: "fun", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wibble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn(String, String) -> String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 6, - character: 22, - }, - end: Position { - line: 6, - character: 22, - }, - }, - new_text: "wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wibble:", - label_details: None, - kind: Some( - Field, - ), - detail: Some( - "String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "0_wibble:", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wobble:", - label_details: None, - kind: Some( - Field, - ), - detail: Some( - "String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "0_wobble:", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +fun + kind: Function + detail: fn() -> String + sort: 2_fun + desc: app + edits: + [6:22-6:22]: "fun" +wibble + kind: Function + detail: fn(String, String) -> String + sort: 2_wibble + desc: app + edits: + [6:22-6:22]: "wibble" +wibble: + kind: Field + detail: String + sort: 0_wibble: +wobble: + kind: Field + detail: String + sort: 0_wobble: diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_imported_function_labels.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_imported_function_labels.snap index 8b44ccc5d..c163d8995 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_imported_function_labels.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_imported_function_labels.snap @@ -10,155 +10,45 @@ fn fun() { // completion inside parens below includes labels ----- Completion content ----- -[ - CompletionItem { - label: "dep.wibble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn(String, String) -> String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 4, - character: 26, - }, - end: Position { - line: 4, - character: 26, - }, - }, - new_text: "dep.wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "fun", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_fun", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 4, - character: 26, - }, - end: Position { - line: 4, - character: 26, - }, - }, - new_text: "fun", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wibble:", - label_details: None, - kind: Some( - Field, - ), - detail: Some( - "String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "0_wibble:", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wobble:", - label_details: None, - kind: Some( - Field, - ), - detail: Some( - "String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "0_wobble:", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.wibble + kind: Function + detail: fn(String, String) -> String + sort: 3_dep.wibble + desc: app + edits: + [4:26-4:26]: "dep.wibble" +fun + kind: Function + detail: fn() -> String + sort: 2_fun + desc: app + edits: + [4:26-4:26]: "fun" +wibble: + kind: Field + detail: String + sort: 0_wibble: +wobble: + kind: Field + detail: String + sort: 0_wobble: diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_imported_record_labels.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_imported_record_labels.snap index 6263a3d78..93e3fcd9f 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_imported_record_labels.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_imported_record_labels.snap @@ -10,155 +10,45 @@ fn fun() { // completion inside parens below includes labels ----- Completion content ----- -[ - CompletionItem { - label: "dep.Wibble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Constructor, - ), - detail: Some( - "fn(String, Int) -> Wibble", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 4, - character: 26, - }, - end: Position { - line: 4, - character: 26, - }, - }, - new_text: "dep.Wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "fun", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Wibble", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_fun", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 4, - character: 26, - }, - end: Position { - line: 4, - character: 26, - }, - }, - new_text: "fun", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wibble:", - label_details: None, - kind: Some( - Field, - ), - detail: Some( - "String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "0_wibble:", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wobble:", - label_details: None, - kind: Some( - Field, - ), - detail: Some( - "Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "0_wobble:", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.Wibble + kind: Constructor + detail: fn(String, Int) -> Wibble + sort: 3_dep.Wibble + desc: app + edits: + [4:26-4:26]: "dep.Wibble" +fun + kind: Function + detail: fn() -> Wibble + sort: 2_fun + desc: app + edits: + [4:26-4:26]: "fun" +wibble: + kind: Field + detail: String + sort: 0_wibble: +wobble: + kind: Field + detail: Int + sort: 0_wobble: diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_outside_a_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_outside_a_function.snap index 86ae9a8ad..dc1cf4c3a 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_outside_a_function.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_outside_a_function.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 142 expression: "\n\npub fn main() {\n 0\n}" --- | @@ -10,4 +11,3 @@ pub fn main() { ----- Completion content ----- -[] diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_prelude_values.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_prelude_values.snap new file mode 100644 index 000000000..a4d53f3f7 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_prelude_values.snap @@ -0,0 +1,37 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\npub fn main() {\n let my_bool = T\n}\n" +--- +pub fn main() { + let my_bool = T| +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +main + kind: Function + detail: fn() -> a + sort: 2_main + desc: app + edits: + [2:16-2:16]: "main" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_private_record_access.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_private_record_access.snap index df00a04c9..68840d790 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_private_record_access.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_private_record_access.snap @@ -14,31 +14,27 @@ fn fun() { ----- Completion content ----- -[ - CompletionItem { - label: "wobble", - label_details: None, - kind: Some( - Field, - ), - detail: Some( - "Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "1_wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +wobble + kind: Field + detail: Int + sort: 1_wobble diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_record_access.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_record_access.snap index 9b7d2f792..55f348bf0 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_record_access.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_record_access.snap @@ -14,31 +14,27 @@ fn fun() { ----- Completion content ----- -[ - CompletionItem { - label: "wobble", - label_details: None, - kind: Some( - Field, - ), - detail: Some( - "Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "1_wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +wobble + kind: Field + detail: Int + sort: 1_wobble diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_record_labels.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_record_labels.snap index 953e234d7..677af8e18 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_record_labels.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__completions_for_record_labels.snap @@ -12,155 +12,45 @@ fn fun() { // completion inside parens below includes labels ----- Completion content ----- -[ - CompletionItem { - label: "Wibble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Constructor, - ), - detail: Some( - "fn(String, Int) -> Wibble", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 6, - character: 22, - }, - end: Position { - line: 6, - character: 22, - }, - }, - new_text: "Wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "fun", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Wibble", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_fun", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 6, - character: 22, - }, - end: Position { - line: 6, - character: 22, - }, - }, - new_text: "fun", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wibble:", - label_details: None, - kind: Some( - Field, - ), - detail: Some( - "String", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "0_wibble:", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wobble:", - label_details: None, - kind: Some( - Field, - ), - detail: Some( - "Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "0_wobble:", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +Wibble + kind: Constructor + detail: fn(String, Int) -> Wibble + sort: 2_Wibble + desc: app + edits: + [6:22-6:22]: "Wibble" +fun + kind: Function + detail: fn() -> Wibble + sort: 2_fun + desc: app + edits: + [6:22-6:22]: "fun" +wibble: + kind: Field + detail: String + sort: 0_wibble: +wobble: + kind: Field + detail: Int + sort: 0_wobble: diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_custom_type_definition.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_custom_type_definition.snap index 16d0639c0..0827a9209 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_custom_type_definition.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_custom_type_definition.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 523 expression: "\npub type Wibble {\n Wobble\n}" --- pub type Wibble { @@ -8,281 +9,45 @@ pub type Wibble { ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Wibble", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 2, - character: 0, - }, - end: Position { - line: 2, - character: 0, - }, - }, - new_text: "Wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +Wibble + kind: Class + detail: Type + sort: 2_Wibble + edits: + [2:0-2:0]: "Wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_function_arguments.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_function_arguments.snap index ca706108b..2987b801b 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_function_arguments.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_function_arguments.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 522 expression: "\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}\n" --- pub fn wibble( @@ -10,239 +11,39 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_type_alias.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_type_alias.snap index bc842915e..40eb4ecfe 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_type_alias.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__for_type_alias.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 535 expression: "\npub type Wibble = Result(\n String,\n String\n)\n" --- pub type Wibble = Result( @@ -9,281 +10,45 @@ pub type Wibble = Result( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Wibble", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 2, - character: 0, - }, - end: Position { - line: 2, - character: 0, - }, - }, - new_text: "Wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +Wibble + kind: Class + detail: Type + sort: 2_Wibble + edits: + [2:0-2:0]: "Wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_adds_extra_new_line_if_import_exists_below_other_definitions.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_adds_extra_new_line_if_import_exists_below_other_definitions.snap index 9d0c2a31b..e9bf68a00 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_adds_extra_new_line_if_import_exists_below_other_definitions.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_adds_extra_new_line_if_import_exists_below_other_definitions.snap @@ -7,70 +7,31 @@ import dep2 ----- Completion content ----- -[ - CompletionItem { - label: "dep.wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.wobble", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 0, - character: 0, - }, - end: Position { - line: 0, - character: 0, - }, - }, - new_text: "import dep\n\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.wobble + kind: Function + detail: fn() -> Nil + sort: 5_dep.wobble + desc: dep + edits: + [1:0-1:0]: "dep.wobble" + [0:0-0:0]: "import dep\n\n" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_adds_extra_new_line_if_no_imports.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_adds_extra_new_line_if_no_imports.snap index df3996d94..1a20dabdc 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_adds_extra_new_line_if_no_imports.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_adds_extra_new_line_if_no_imports.snap @@ -3,70 +3,31 @@ source: compiler-core/src/language_server/tests/completion.rs expression: "" --- ----- Completion content ----- -[ - CompletionItem { - label: "dep.wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.wobble", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 0, - character: 0, - }, - end: Position { - line: 0, - character: 0, - }, - }, - new_text: "import dep\n\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.wobble + kind: Function + detail: fn() -> Nil + sort: 5_dep.wobble + desc: dep + edits: + [1:0-1:0]: "dep.wobble" + [0:0-0:0]: "import dep\n\n" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_does_not_add_extra_new_line_if_imports_exist.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_does_not_add_extra_new_line_if_imports_exist.snap index 90acc13ae..a6b4e4387 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_does_not_add_extra_new_line_if_imports_exist.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_does_not_add_extra_new_line_if_imports_exist.snap @@ -3,70 +3,31 @@ source: compiler-core/src/language_server/tests/completion.rs expression: "" --- ----- Completion content ----- -[ - CompletionItem { - label: "dep.wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "dep.wobble", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 0, - character: 0, - }, - end: Position { - line: 0, - character: 0, - }, - }, - new_text: "import dep\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.wobble + kind: Function + detail: fn() -> Nil + sort: 5_dep.wobble + desc: dep + edits: + [3:0-3:0]: "dep.wobble" + [0:0-0:0]: "import dep\n" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_does_not_add_extra_new_line_if_newline_exists.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_does_not_add_extra_new_line_if_newline_exists.snap index 003a3da8f..552ddb1e5 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_does_not_add_extra_new_line_if_newline_exists.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_does_not_add_extra_new_line_if_newline_exists.snap @@ -3,70 +3,31 @@ source: compiler-core/src/language_server/tests/completion.rs expression: "" --- ----- Completion content ----- -[ - CompletionItem { - label: "dep.wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 2, - character: 0, - }, - end: Position { - line: 2, - character: 0, - }, - }, - new_text: "dep.wobble", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 0, - character: 0, - }, - end: Position { - line: 0, - character: 0, - }, - }, - new_text: "import dep\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.wobble + kind: Function + detail: fn() -> Nil + sort: 5_dep.wobble + desc: dep + edits: + [2:0-2:0]: "dep.wobble" + [0:0-0:0]: "import dep\n" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function.snap index 04c8b8589..d23109558 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function.snap @@ -6,70 +6,31 @@ expression: "\n" ----- Completion content ----- -[ - CompletionItem { - label: "dep.wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.wobble", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 0, - character: 0, - }, - end: Position { - line: 0, - character: 0, - }, - }, - new_text: "import dep\n\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.wobble + kind: Function + detail: fn() -> Nil + sort: 5_dep.wobble + desc: dep + edits: + [1:0-1:0]: "dep.wobble" + [0:0-0:0]: "import dep\n\n" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function_from_deep_module.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function_from_deep_module.snap index 4ecaff5dc..49e20506e 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function_from_deep_module.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function_from_deep_module.snap @@ -6,70 +6,31 @@ expression: "\n" ----- Completion content ----- -[ - CompletionItem { - label: "dep.wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "a/b/dep", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.wobble", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 0, - character: 0, - }, - end: Position { - line: 0, - character: 0, - }, - }, - new_text: "import a/b/dep\n\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.wobble + kind: Function + detail: fn() -> Nil + sort: 5_dep.wobble + desc: a/b/dep + edits: + [1:0-1:0]: "dep.wobble" + [0:0-0:0]: "import a/b/dep\n\n" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function_with_existing_imports.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function_with_existing_imports.snap index c829ea956..03b3d292b 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function_with_existing_imports.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_module_function_with_existing_imports.snap @@ -10,119 +10,38 @@ import dep2 ----- Completion content ----- -[ - CompletionItem { - label: "dep.wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "dep", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.wobble", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 0, - character: 0, - }, - end: Position { - line: 0, - character: 0, - }, - }, - new_text: "import dep\n\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep2.wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep2.wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep2.wobble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.wobble + kind: Function + detail: fn() -> Nil + sort: 5_dep.wobble + desc: dep + edits: + [1:0-1:0]: "dep.wobble" + [0:0-0:0]: "import dep\n\n" +dep2.wobble + kind: Function + detail: fn() -> Nil + sort: 3_dep2.wobble + desc: app + edits: + [1:0-1:0]: "dep2.wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type.snap index 4a8f9c5ae..634028a03 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 690 expression: "\n\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}\n" --- pub fn wibble( @@ -10,297 +11,46 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "dep.Zoo", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 0, - character: 0, - }, - end: Position { - line: 0, - character: 0, - }, - }, - new_text: "import dep\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +dep.Zoo + kind: Class + detail: Type + sort: 5_dep.Zoo + edits: + [3:0-3:0]: "dep.Zoo" + [0:0-0:0]: "import dep\n" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_from_deep_module.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_from_deep_module.snap index d3ed27a7d..993e2b039 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_from_deep_module.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_from_deep_module.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 769 expression: "\n\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}\n" --- pub fn wibble( @@ -10,297 +11,46 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "dep.Zoo", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 0, - character: 0, - }, - end: Position { - line: 0, - character: 0, - }, - }, - new_text: "import a/b/dep\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +dep.Zoo + kind: Class + detail: Type + sort: 5_dep.Zoo + edits: + [3:0-3:0]: "dep.Zoo" + [0:0-0:0]: "import a/b/dep\n" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_with_existing_imports.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_with_existing_imports.snap index 3e4f7119e..13615f1be 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_with_existing_imports.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_with_existing_imports.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 746 expression: "\n//// Some module comments\n// Some other whitespace\n\nimport dep2\n\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}\n" --- //// Some module comments @@ -15,339 +16,52 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 7, - character: 0, - }, - end: Position { - line: 7, - character: 0, - }, - }, - new_text: "dep.Zoo", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 4, - character: 0, - }, - end: Position { - line: 4, - character: 0, - }, - }, - new_text: "import dep\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep2.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep2.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 7, - character: 0, - }, - end: Position { - line: 7, - character: 0, - }, - }, - new_text: "dep2.Zoo", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +dep.Zoo + kind: Class + detail: Type + sort: 5_dep.Zoo + edits: + [7:0-7:0]: "dep.Zoo" + [4:0-4:0]: "import dep\n" +dep2.Zoo + kind: Class + detail: Type + sort: 3_dep2.Zoo + edits: + [7:0-7:0]: "dep2.Zoo" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_with_existing_imports_at_top.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_with_existing_imports_at_top.snap index 9dad35686..20531298b 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_with_existing_imports_at_top.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__importable_type_with_existing_imports_at_top.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 715 expression: "import dep2\n\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}\n" --- import dep2 @@ -12,339 +13,52 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "5_dep.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "dep.Zoo", - }, - ), - ), - additional_text_edits: Some( - [ - TextEdit { - range: Range { - start: Position { - line: 0, - character: 0, - }, - end: Position { - line: 0, - character: 0, - }, - }, - new_text: "import dep\n", - }, - ], - ), - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep2.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep2.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "dep2.Zoo", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +dep.Zoo + kind: Class + detail: Type + sort: 5_dep.Zoo + edits: + [3:0-3:0]: "dep.Zoo" + [0:0-0:0]: "import dep\n" +dep2.Zoo + kind: Class + detail: Type + sort: 3_dep2.Zoo + edits: + [3:0-3:0]: "dep2.Zoo" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_module_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_module_function.snap index 197eab685..0b622f55f 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_module_function.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_module_function.snap @@ -7,54 +7,30 @@ import dep ----- Completion content ----- -[ - CompletionItem { - label: "dep.wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.wobble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.wobble + kind: Function + detail: fn() -> Nil + sort: 3_dep.wobble + desc: app + edits: + [1:0-1:0]: "dep.wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_public_enum.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_public_enum.snap index 1bcb850a1..3c2d45558 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_public_enum.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_public_enum.snap @@ -7,103 +7,37 @@ import dep ----- Completion content ----- -[ - CompletionItem { - label: "dep.Left", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Direction", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Left", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.Left", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Right", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Direction", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Right", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.Right", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.Left + kind: EnumMember + detail: Direction + sort: 3_dep.Left + desc: app + edits: + [1:0-1:0]: "dep.Left" +dep.Right + kind: EnumMember + detail: Direction + sort: 3_dep.Right + desc: app + edits: + [1:0-1:0]: "dep.Right" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_public_record.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_public_record.snap index 9d53c3889..3793701d9 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_public_record.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_public_record.snap @@ -7,54 +7,30 @@ import dep ----- Completion content ----- -[ - CompletionItem { - label: "dep.Box", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Constructor, - ), - detail: Some( - "fn(Int) -> Box", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Box", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.Box", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.Box + kind: Constructor + detail: fn(Int) -> Box + sort: 3_dep.Box + desc: app + edits: + [1:0-1:0]: "dep.Box" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type.snap index 6e94c4f43..dddcead5f 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 566 expression: "import dep\n\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}\n" --- import dep @@ -12,281 +13,45 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "dep.Zoo", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +dep.Zoo + kind: Class + detail: Type + sort: 3_dep.Zoo + edits: + [3:0-3:0]: "dep.Zoo" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot.snap index 01b94a4bc..bda49217b 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 587 expression: "import dep\n\npub fn wibble(\n _: dep.Zoo,\n) -> Nil {\n Nil\n}\n" --- import dep @@ -12,281 +13,45 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 5, - }, - end: Position { - line: 3, - character: 12, - }, - }, - new_text: "dep.Zoo", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +dep.Zoo + kind: Class + detail: Type + sort: 3_dep.Zoo + edits: + [3:5-3:5]: "dep.Zoo" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot_other_matching_modules.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot_other_matching_modules.snap index 29f56161d..271986de5 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot_other_matching_modules.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot_other_matching_modules.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 613 expression: "import dep\nimport dep2\n\npub fn wibble(\n _: dep.Zoo,\n) -> Nil {\n Nil\n}\n" --- import dep @@ -13,281 +14,45 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 4, - character: 5, - }, - end: Position { - line: 4, - character: 12, - }, - }, - new_text: "dep.Zoo", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +dep.Zoo + kind: Class + detail: Type + sort: 3_dep.Zoo + edits: + [4:5-4:5]: "dep.Zoo" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot_other_modules.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot_other_modules.snap index 01b94a4bc..7ffd644db 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot_other_modules.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_after_dot_other_modules.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 640 expression: "import dep\n\npub fn wibble(\n _: dep.Zoo,\n) -> Nil {\n Nil\n}\n" --- import dep @@ -12,281 +13,45 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 5, - }, - end: Position { - line: 3, - character: 12, - }, - }, - new_text: "dep.Zoo", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +dep.Zoo + kind: Class + detail: Type + sort: 3_dep.Zoo + edits: + [3:5-3:5]: "dep.Zoo" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_mid_phrase_other_modules.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_mid_phrase_other_modules.snap index 3552bb1f6..c0224c076 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_mid_phrase_other_modules.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_type_cursor_mid_phrase_other_modules.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 667 expression: "import dep\n\npub fn wibble(\n _: dep.Zoo,\n) -> Nil {\n Nil\n}\n" --- import dep @@ -12,281 +13,45 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 5, - }, - end: Position { - line: 3, - character: 12, - }, - }, - new_text: "dep.Zoo", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +dep.Zoo + kind: Class + detail: Type + sort: 3_dep.Zoo + edits: + [3:5-3:5]: "dep.Zoo" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_module_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_module_function.snap index 3b90d12ec..5f4ce76cb 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_module_function.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_module_function.snap @@ -7,103 +7,37 @@ import dep.{wobble} ----- Completion content ----- -[ - CompletionItem { - label: "dep.wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.wobble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Nil", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "wobble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.wobble + kind: Function + detail: fn() -> Nil + sort: 3_dep.wobble + desc: app + edits: + [1:0-1:0]: "dep.wobble" +wobble + kind: Function + detail: fn() -> Nil + sort: 3_wobble + desc: app + edits: + [1:0-1:0]: "wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_public_enum.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_public_enum.snap index 956b1ca8c..c86747277 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_public_enum.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_public_enum.snap @@ -7,152 +7,44 @@ import dep.{Left} ----- Completion content ----- -[ - CompletionItem { - label: "Left", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Direction", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_Left", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Left", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Left", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Direction", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Left", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.Left", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Right", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Direction", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Right", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.Right", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Left + kind: EnumMember + detail: Direction + sort: 3_Left + desc: app + edits: + [1:0-1:0]: "Left" +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.Left + kind: EnumMember + detail: Direction + sort: 3_dep.Left + desc: app + edits: + [1:0-1:0]: "dep.Left" +dep.Right + kind: EnumMember + detail: Direction + sort: 3_dep.Right + desc: app + edits: + [1:0-1:0]: "dep.Right" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_public_record.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_public_record.snap index 843df091e..0aa0fef03 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_public_record.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__imported_unqualified_public_record.snap @@ -7,103 +7,37 @@ import dep.{Box} ----- Completion content ----- -[ - CompletionItem { - label: "Box", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Constructor, - ), - detail: Some( - "fn(Int) -> Box", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_Box", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Box", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Box", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Constructor, - ), - detail: Some( - "fn(Int) -> Box", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Box", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.Box", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Box + kind: Constructor + detail: fn(Int) -> Box + sort: 3_Box + desc: app + edits: + [1:0-1:0]: "Box" +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.Box + kind: Constructor + detail: fn(Int) -> Box + sort: 3_dep.Box + desc: app + edits: + [1:0-1:0]: "dep.Box" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__in_custom_type_definition.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__in_custom_type_definition.snap index 616a603e3..ae3e85238 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__in_custom_type_definition.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__in_custom_type_definition.snap @@ -6,4 +6,23 @@ expression: import dep ----- Completion content ----- -[] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_modules_from_same_package_are_included.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_modules_from_same_package_are_included.snap index 50b2a2ef6..f7c657b7e 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_modules_from_same_package_are_included.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_modules_from_same_package_are_included.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1130 expression: "import gleam\n\npub fn main() {\n 0\n}" --- |import gleam @@ -10,43 +11,7 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "app/internal", - label_details: None, - kind: Some( - Module, - ), - detail: None, - documentation: None, - deprecated: None, - preselect: None, - sort_text: None, - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 0, - character: 7, - }, - end: Position { - line: 0, - character: 12, - }, - }, - new_text: "app/internal", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +app/internal + kind: Module + edits: + [0:7-0:7]: "app/internal" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_a_dependency_are_ignored.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_a_dependency_are_ignored.snap index ef5fa701d..d9ffaf814 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_a_dependency_are_ignored.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_a_dependency_are_ignored.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 858 expression: "import dep\n\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}" --- import dep @@ -12,239 +13,39 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_root_package_are_in_the_completions.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_root_package_are_in_the_completions.snap index 81064c52d..48ccbd9a4 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_root_package_are_in_the_completions.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_root_package_are_in_the_completions.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 838 expression: "import dep\n\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}" --- import dep @@ -12,323 +13,51 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Alias", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Alias", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "dep.Alias", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.AnotherType", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.AnotherType", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "dep.AnotherType", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +dep.Alias + kind: Class + detail: Type + sort: 3_dep.Alias + edits: + [3:0-3:0]: "dep.Alias" +dep.AnotherType + kind: Class + detail: Type + sort: 3_dep.AnotherType + edits: + [3:0-3:0]: "dep.AnotherType" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_the_same_module_are_in_the_completions.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_the_same_module_are_in_the_completions.snap index 06aba4c5d..dd73a0e8a 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_the_same_module_are_in_the_completions.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_types_from_the_same_module_are_in_the_completions.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 866 expression: "\n@internal pub type Alias = Result(Int, String)\n@internal pub type AnotherType {\n Wibble\n}\n" --- @internal pub type Alias = Result(Int, String) @@ -9,323 +10,51 @@ expression: "\n@internal pub type Alias = Result(Int, String)\n@internal pub typ ----- Completion content ----- -[ - CompletionItem { - label: "Alias", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Alias", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "Alias", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "AnotherType", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_AnotherType", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "AnotherType", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Alias + kind: Class + detail: Type + sort: 2_Alias + edits: + [3:0-3:0]: "Alias" +AnotherType + kind: Class + detail: Type + sort: 2_AnotherType + edits: + [3:0-3:0]: "AnotherType" +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_a_dependency_are_ignored.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_a_dependency_are_ignored.snap index 616a603e3..ae3e85238 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_a_dependency_are_ignored.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_a_dependency_are_ignored.snap @@ -6,4 +6,23 @@ expression: import dep ----- Completion content ----- -[] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_root_package_are_in_the_completions.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_root_package_are_in_the_completions.snap index feb89a4fd..3f40425da 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_root_package_are_in_the_completions.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_root_package_are_in_the_completions.snap @@ -6,201 +6,51 @@ expression: import dep ----- Completion content ----- -[ - CompletionItem { - label: "dep.Wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Wibble", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.Wobble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.main", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.main", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.main", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.random_float", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Float", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.random_float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.random_float", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.wibble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Constant, - ), - detail: Some( - "Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "dep.wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +dep.Wobble + kind: EnumMember + detail: Wibble + sort: 3_dep.Wobble + desc: app + edits: + [1:0-1:0]: "dep.Wobble" +dep.main + kind: Function + detail: fn() -> Int + sort: 3_dep.main + desc: app + edits: + [1:0-1:0]: "dep.main" +dep.random_float + kind: Function + detail: fn() -> Float + sort: 3_dep.random_float + desc: app + edits: + [1:0-1:0]: "dep.random_float" +dep.wibble + kind: Constant + detail: Int + sort: 3_dep.wibble + desc: app + edits: + [1:0-1:0]: "dep.wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_the_same_module_are_in_the_completions.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_the_same_module_are_in_the_completions.snap index 2cbc17fa5..1c70b07b9 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_the_same_module_are_in_the_completions.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__internal_values_from_the_same_module_are_in_the_completions.snap @@ -11,201 +11,51 @@ expression: "\n@external(erlang, \"rand\", \"uniform\")\n@internal pub fn random ----- Completion content ----- -[ - CompletionItem { - label: "Wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Wibble", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Wobble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "main", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_main", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "main", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "random_float", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Float", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_random_float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "random_float", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "wibble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Constant, - ), - detail: Some( - "Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_wibble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "wibble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +Wobble + kind: EnumMember + detail: Wibble + sort: 2_Wobble + desc: app + edits: + [1:0-1:0]: "Wobble" +main + kind: Function + detail: fn() -> Int + sort: 2_main + desc: app + edits: + [1:0-1:0]: "main" +random_float + kind: Function + detail: fn() -> Float + sort: 2_random_float + desc: app + edits: + [1:0-1:0]: "random_float" +wibble + kind: Constant + detail: Int + sort: 2_wibble + desc: app + edits: + [1:0-1:0]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_private_type.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_private_type.snap index e75bdab35..4d9cc2eb5 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_private_type.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_private_type.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 808 expression: "\ntype Zoo = Int\n\npub fn wibble(\n x: String,\n) -> String {\n \"ok\"\n}\n" --- type Zoo = Int @@ -12,281 +13,45 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 4, - character: 0, - }, - end: Position { - line: 4, - character: 0, - }, - }, - new_text: "Zoo", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +Zoo + kind: Class + detail: Type + sort: 2_Zoo + edits: + [4:0-4:0]: "Zoo" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_enum.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_enum.snap index 85f87bcbf..facff1f94 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_enum.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_enum.snap @@ -10,103 +10,37 @@ pub type Direction { ----- Completion content ----- -[ - CompletionItem { - label: "Left", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Direction", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Left", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Left", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Right", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Direction", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Right", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Right", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Left + kind: EnumMember + detail: Direction + sort: 2_Left + desc: app + edits: + [1:0-1:0]: "Left" +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +Right + kind: EnumMember + detail: Direction + sort: 2_Right + desc: app + edits: + [1:0-1:0]: "Right" +True + kind: EnumMember + detail: gleam + sort: 4_True diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_enum_with_documentation.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_enum_with_documentation.snap index 7709b1008..ea909bf33 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_enum_with_documentation.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_enum_with_documentation.snap @@ -12,117 +12,39 @@ pub type Direction { ----- Completion content ----- -[ - CompletionItem { - label: "Left", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Direction", - ), - documentation: Some( - MarkupContent( - MarkupContent { - kind: Markdown, - value: " Hello\n", - }, - ), - ), - deprecated: None, - preselect: None, - sort_text: Some( - "2_Left", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Left", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Right", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Direction", - ), - documentation: Some( - MarkupContent( - MarkupContent { - kind: Markdown, - value: " Goodbye\n", - }, - ), - ), - deprecated: None, - preselect: None, - sort_text: Some( - "2_Right", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Right", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Left + kind: EnumMember + detail: Direction + sort: 2_Left + desc: app + docs: " Hello\n" + edits: + [1:0-1:0]: "Left" +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +Right + kind: EnumMember + detail: Direction + sort: 2_Right + desc: app + docs: " Goodbye\n" + edits: + [1:0-1:0]: "Right" +True + kind: EnumMember + detail: gleam + sort: 4_True diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_function.snap index 2c3a2c338..1ced81403 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_function.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_function.snap @@ -9,54 +9,30 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "main", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_main", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "main", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +main + kind: Function + detail: fn() -> Int + sort: 2_main + desc: app + edits: + [1:0-1:0]: "main" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_function_with_documentation.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_function_with_documentation.snap index a13c5de9a..cd84d4de7 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_function_with_documentation.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_function_with_documentation.snap @@ -10,61 +10,31 @@ pub fn main() { ----- Completion content ----- -[ - CompletionItem { - label: "main", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Int", - ), - documentation: Some( - MarkupContent( - MarkupContent { - kind: Markdown, - value: " Hello\n", - }, - ), - ), - deprecated: None, - preselect: None, - sort_text: Some( - "2_main", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "main", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +main + kind: Function + detail: fn() -> Int + sort: 2_main + desc: app + docs: " Hello\n" + edits: + [1:0-1:0]: "main" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_record.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_record.snap index 1973cfdfe..94c3dcecf 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_record.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_record.snap @@ -10,61 +10,31 @@ pub type Box { ----- Completion content ----- -[ - CompletionItem { - label: "Box", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Constructor, - ), - detail: Some( - "fn(Int, Int, Float) -> Box", - ), - documentation: Some( - MarkupContent( - MarkupContent { - kind: Markdown, - value: " Hello\n", - }, - ), - ), - deprecated: None, - preselect: None, - sort_text: Some( - "2_Box", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Box", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Box + kind: Constructor + detail: fn(Int, Int, Float) -> Box + sort: 2_Box + desc: app + docs: " Hello\n" + edits: + [1:0-1:0]: "Box" +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_record_with_documentation.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_record_with_documentation.snap index d15010b1e..7f78d0a5a 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_record_with_documentation.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_public_record_with_documentation.snap @@ -9,54 +9,30 @@ pub type Box { ----- Completion content ----- -[ - CompletionItem { - label: "Box", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Constructor, - ), - detail: Some( - "fn(Int, Int, Float) -> Box", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Box", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Box", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Box + kind: Constructor + detail: fn(Int, Int, Float) -> Box + sort: 2_Box + desc: app + edits: + [1:0-1:0]: "Box" +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable.snap new file mode 100644 index 000000000..b9400584b --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable.snap @@ -0,0 +1,56 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\npub fn main(wibble: Int) {\n let wobble = 1\n w\n\n let wabble = 2\n}\n" +--- +pub fn main(wibble: Int) { + let wobble = 1 + w| + + let wabble = 2 +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +main + kind: Function + detail: fn(Int) -> Int + sort: 2_main + desc: app + edits: + [3:2-3:2]: "main" +wibble + kind: Variable + detail: Int + sort: 2_wibble + desc: app + docs: "A locally defined variable." + edits: + [3:2-3:2]: "wibble" +wobble + kind: Variable + detail: Int + sort: 2_wobble + desc: app + docs: "A locally defined variable." + edits: + [3:2-3:2]: "wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_anonymous_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_anonymous_function.snap new file mode 100644 index 000000000..9ff78e591 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_anonymous_function.snap @@ -0,0 +1,46 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\npub fn main() {\n let add_one = fn(wibble: Int) { wibble + 1 }\n add_one(1)\n}\n" +--- +pub fn main() { + let add_one = fn(wibble: Int) { wibble| + 1 } + add_one(1) +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +main + kind: Function + detail: fn() -> Int + sort: 2_main + desc: app + edits: + [2:34-2:34]: "main" +wibble + kind: Variable + detail: Int + sort: 2_wibble + desc: app + docs: "A locally defined variable." + edits: + [2:34-2:34]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_as.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_as.snap new file mode 100644 index 000000000..18410f7e1 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_as.snap @@ -0,0 +1,54 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\nfn wibble() {\n let b as c = 5\n\n}\n" +--- +fn wibble() { + let b as c = 5 +| +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +b + kind: Variable + detail: Int + sort: 2_b + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "b" +c + kind: Variable + detail: Int + sort: 2_c + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "c" +wibble + kind: Function + detail: fn() -> Int + sort: 2_wibble + desc: app + edits: + [3:0-3:0]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_bit_array.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_bit_array.snap new file mode 100644 index 000000000..b9f0b6bd5 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_bit_array.snap @@ -0,0 +1,54 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\nfn wibble() {\n let assert <> as i = <<1:1>>\n\n}\n" +--- +fn wibble() { + let assert <> as i = <<1:1>> +| +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +h + kind: Variable + detail: Int + sort: 2_h + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "h" +i + kind: Variable + detail: BitArray + sort: 2_i + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "i" +wibble + kind: Function + detail: fn() -> BitArray + sort: 2_wibble + desc: app + edits: + [3:0-3:0]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_case_expression.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_case_expression.snap new file mode 100644 index 000000000..27f4b7673 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_case_expression.snap @@ -0,0 +1,48 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\npub fn main() {\n case True {\n True as wibble -> { todo }\n False -> { todo }\n }\n}\n" +--- +pub fn main() { + case True { + True as wibble -> { t|odo } + False -> { todo } + } +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +main + kind: Function + detail: fn() -> a + sort: 2_main + desc: app + edits: + [3:24-3:24]: "main" +wibble + kind: Variable + detail: Bool + sort: 2_wibble + desc: app + docs: "A locally defined variable." + edits: + [3:24-3:24]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_function_call.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_function_call.snap new file mode 100644 index 000000000..ede6f34be --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_function_call.snap @@ -0,0 +1,57 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\nfn add_one(wibble: Int) -> Int {\n wibble + 1\n}\n\npub fn main() {\n let wobble = 1\n add_one(wobble)\n}\n" +--- +fn add_one(wibble: Int) -> Int { + wibble + 1 +} + +pub fn main() { + let wobble = 1 + add_one(wobble|) +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +add_one + kind: Function + detail: fn(Int) -> Int + sort: 2_add_one + desc: app + edits: + [7:10-7:10]: "add_one" +main + kind: Function + detail: fn() -> Int + sort: 2_main + desc: app + edits: + [7:10-7:10]: "main" +wobble + kind: Variable + detail: Int + sort: 2_wobble + desc: app + docs: "A locally defined variable." + edits: + [7:10-7:10]: "wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_args.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_args.snap new file mode 100644 index 000000000..d4d005c9a --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_args.snap @@ -0,0 +1,55 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\npub fn main() {\n let add_one = fn(wibble: Int) { wibble + 1 }\n let wobble = 1\n w\n}\n" +--- +pub fn main() { + let add_one = fn(wibble: Int) { wibble + 1 } + let wobble = 1 + w| +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +add_one + kind: Variable + detail: fn(Int) -> Int + sort: 2_add_one + desc: app + docs: "A locally defined variable." + edits: + [4:2-4:2]: "add_one" +main + kind: Function + detail: fn() -> a + sort: 2_main + desc: app + edits: + [4:2-4:2]: "main" +wobble + kind: Variable + detail: Int + sort: 2_wobble + desc: app + docs: "A locally defined variable." + edits: + [4:2-4:2]: "wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_args_nested.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_args_nested.snap new file mode 100644 index 000000000..663d337ab --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_args_nested.snap @@ -0,0 +1,66 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\npub fn main() {\n let add_one = fn(wibble: Int) {\n let wabble = 1\n let add_two = fn(wobble: Int) { wobble + 2 }\n wibble + add_two(1)\n }\n add_one(1)\n}\n" +--- +pub fn main() { + let add_one = fn(wibble: Int) { + let wabble = 1 + let add_two = fn(wobble: Int) { wobble + 2 } + wibble| + add_two(1) + } + add_one(1) +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +add_two + kind: Variable + detail: fn(Int) -> Int + sort: 2_add_two + desc: app + docs: "A locally defined variable." + edits: + [5:4-5:4]: "add_two" +main + kind: Function + detail: fn() -> Int + sort: 2_main + desc: app + edits: + [5:4-5:4]: "main" +wabble + kind: Variable + detail: Int + sort: 2_wabble + desc: app + docs: "A locally defined variable." + edits: + [5:4-5:4]: "wabble" +wibble + kind: Variable + detail: Int + sort: 2_wibble + desc: app + docs: "A locally defined variable." + edits: + [5:4-5:4]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_returned.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_returned.snap new file mode 100644 index 000000000..16ed6fdad --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_anonymous_function_returned.snap @@ -0,0 +1,65 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\npub fn main() {\n fn(wibble: Int) {\n let wabble = 1\n let add_two = fn(wobble: Int) { wobble + 2 }\n wibble + add_two(1)\n }\n}\n" +--- +pub fn main() { + fn(wibble: Int) { + let wabble = 1 + let add_two = fn(wobble: Int) { wobble + 2 } + wibble| + add_two(1) + } +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +add_two + kind: Variable + detail: fn(Int) -> Int + sort: 2_add_two + desc: app + docs: "A locally defined variable." + edits: + [5:4-5:4]: "add_two" +main + kind: Function + detail: fn() -> fn(Int) -> Int + sort: 2_main + desc: app + edits: + [5:4-5:4]: "main" +wabble + kind: Variable + detail: Int + sort: 2_wabble + desc: app + docs: "A locally defined variable." + edits: + [5:4-5:4]: "wabble" +wibble + kind: Variable + detail: Int + sort: 2_wibble + desc: app + docs: "A locally defined variable." + edits: + [5:4-5:4]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_within_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_within_function.snap new file mode 100644 index 000000000..8a3c15e6b --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignore_within_function.snap @@ -0,0 +1,10 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\nfn main(a, b, z) {\n Nil\n}\n" +--- +fn main(a, b, |z) { + Nil +} + + +----- Completion content ----- diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignored.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignored.snap new file mode 100644 index 000000000..b4588057f --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_ignored.snap @@ -0,0 +1,47 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\nfn wibble() {\n let a = 1\n let _b = 2\n\n}\n" +--- +fn wibble() { + let a = 1 + let _b = 2 +| +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +a + kind: Variable + detail: Int + sort: 2_a + desc: app + docs: "A locally defined variable." + edits: + [4:0-4:0]: "a" +wibble + kind: Function + detail: fn() -> Int + sort: 2_wibble + desc: app + edits: + [4:0-4:0]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_inside_nested_exprs.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_inside_nested_exprs.snap new file mode 100644 index 000000000..67b0cdd65 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_inside_nested_exprs.snap @@ -0,0 +1,57 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\ntype Foo { Bar(List(#(Bool))) }\nfn wibble() {\n Bar([#(!{\n let foo = True\n foo\n })])\n todo\n}\n" +--- +type Foo { Bar(List(#(Bool))) } +fn wibble() { + Bar([#(!{ + let foo = True + foo| + })]) + todo +} + + +----- Completion content ----- +Bar + kind: Constructor + detail: fn(List(#(Bool))) -> Foo + sort: 2_Bar + desc: app + edits: + [5:4-5:4]: "Bar" +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +foo + kind: Variable + detail: Bool + sort: 2_foo + desc: app + docs: "A locally defined variable." + edits: + [5:4-5:4]: "foo" +wibble + kind: Function + detail: fn() -> a + sort: 2_wibble + desc: app + edits: + [5:4-5:4]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_nested_anonymous_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_nested_anonymous_function.snap new file mode 100644 index 000000000..c1ff8d842 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_nested_anonymous_function.snap @@ -0,0 +1,66 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\npub fn main() {\n let add_one = fn(wibble: Int) {\n let wabble = 1\n let add_two = fn(wobble: Int) { wobble + 2 }\n wibble + add_two(1)\n }\n add_one(1)\n}\n" +--- +pub fn main() { + let add_one = fn(wibble: Int) { + let wabble = 1 + let add_two = fn(wobble: Int) { wobble| + 2 } + wibble + add_two(1) + } + add_one(1) +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +main + kind: Function + detail: fn() -> Int + sort: 2_main + desc: app + edits: + [4:36-4:36]: "main" +wabble + kind: Variable + detail: Int + sort: 2_wabble + desc: app + docs: "A locally defined variable." + edits: + [4:36-4:36]: "wabble" +wibble + kind: Variable + detail: Int + sort: 2_wibble + desc: app + docs: "A locally defined variable." + edits: + [4:36-4:36]: "wibble" +wobble + kind: Variable + detail: Int + sort: 2_wobble + desc: app + docs: "A locally defined variable." + edits: + [4:36-4:36]: "wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_pipe.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_pipe.snap new file mode 100644 index 000000000..be6479242 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_pipe.snap @@ -0,0 +1,55 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\npub fn main() {\n let add_one = fn(wibble: Int) { wibble + 1 }\n let wobble = 1\n wobble |> add_one\n}\n" +--- +pub fn main() { + let add_one = fn(wibble: Int) { wibble + 1 } + let wobble = 1 + wobble |> add_one| +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +add_one + kind: Variable + detail: fn(Int) -> Int + sort: 2_add_one + desc: app + docs: "A locally defined variable." + edits: + [4:12-4:12]: "add_one" +main + kind: Function + detail: fn() -> Int + sort: 2_main + desc: app + edits: + [4:12-4:12]: "main" +wobble + kind: Variable + detail: Int + sort: 2_wobble + desc: app + docs: "A locally defined variable." + edits: + [4:12-4:12]: "wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_pipe_with_args.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_pipe_with_args.snap new file mode 100644 index 000000000..17ae84459 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_pipe_with_args.snap @@ -0,0 +1,64 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\npub fn main() {\n let add_one = fn(wibble: Int, wobble: Int) { wibble + wobble }\n let wobble = 1\n let wibble = 2\n wobble |> add_one(1, wibble)\n}\n" +--- +pub fn main() { + let add_one = fn(wibble: Int, wobble: Int) { wibble + wobble } + let wobble = 1 + let wibble = 2 + wobble |> add_one(1, wibble|) +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +add_one + kind: Variable + detail: fn(Int, Int) -> Int + sort: 2_add_one + desc: app + docs: "A locally defined variable." + edits: + [5:23-5:23]: "add_one" +main + kind: Function + detail: fn() -> a + sort: 2_main + desc: app + edits: + [5:23-5:23]: "main" +wibble + kind: Variable + detail: Int + sort: 2_wibble + desc: app + docs: "A locally defined variable." + edits: + [5:23-5:23]: "wibble" +wobble + kind: Variable + detail: Int + sort: 2_wobble + desc: app + docs: "A locally defined variable." + edits: + [5:23-5:23]: "wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_string.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_string.snap new file mode 100644 index 000000000..3004ff412 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_string.snap @@ -0,0 +1,46 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\nfn wibble() {\n let assert \"a\" <> j = \"ab\"\n\n}\n" +--- +fn wibble() { + let assert "a" <> j = "ab" +| +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +j + kind: Variable + detail: String + sort: 2_j + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "j" +wibble + kind: Function + detail: fn() -> String + sort: 2_wibble + desc: app + edits: + [3:0-3:0]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_tuple.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_tuple.snap new file mode 100644 index 000000000..f9478ac9d --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__local_variable_tuple.snap @@ -0,0 +1,70 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +expression: "\nfn wibble() {\n let assert #([d, e] as f, g) = #([0, 1], 2)\n\n}\n" +--- +fn wibble() { + let assert #([d, e] as f, g) = #([0, 1], 2) +| +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +d + kind: Variable + detail: Int + sort: 2_d + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "d" +e + kind: Variable + detail: Int + sort: 2_e + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "e" +f + kind: Variable + detail: List(Int) + sort: 2_f + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "f" +g + kind: Variable + detail: Int + sort: 2_g + desc: app + docs: "A locally defined variable." + edits: + [3:0-3:0]: "g" +wibble + kind: Function + detail: fn() -> #(List(Int), Int) + sort: 2_wibble + desc: app + edits: + [3:0-3:0]: "wibble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__opaque_type.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__opaque_type.snap index 03ef1c406..a218bc197 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__opaque_type.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__opaque_type.snap @@ -9,54 +9,30 @@ pub opaque type Wibble { ----- Completion content ----- -[ - CompletionItem { - label: "Wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Wibble", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Wobble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +Wobble + kind: EnumMember + detail: Wibble + sort: 2_Wobble + desc: app + edits: + [1:0-1:0]: "Wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_function.snap index ffa04e8b2..4ae58cecc 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_function.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_function.snap @@ -9,54 +9,30 @@ fn private() { ----- Completion content ----- -[ - CompletionItem { - label: "private", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - Function, - ), - detail: Some( - "fn() -> Int", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_private", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "private", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +private + kind: Function + detail: fn() -> Int + sort: 2_private + desc: app + edits: + [1:0-1:0]: "private" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_function_in_dep.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_function_in_dep.snap index 616a603e3..ae3e85238 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_function_in_dep.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_function_in_dep.snap @@ -6,4 +6,23 @@ expression: import dep ----- Completion content ----- -[] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_type.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_type.snap index 166ef27bf..433ef82ee 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_type.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_type.snap @@ -9,54 +9,30 @@ type Wibble { ----- Completion content ----- -[ - CompletionItem { - label: "Wobble", - label_details: Some( - CompletionItemLabelDetails { - detail: None, - description: Some( - "app", - ), - }, - ), - kind: Some( - EnumMember, - ), - detail: Some( - "Wibble", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "2_Wobble", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 1, - character: 0, - }, - end: Position { - line: 1, - character: 0, - }, - }, - new_text: "Wobble", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +Wobble + kind: EnumMember + detail: Wibble + sort: 2_Wobble + desc: app + edits: + [1:0-1:0]: "Wobble" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_type_in_dep.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_type_in_dep.snap index 616a603e3..ae3e85238 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_type_in_dep.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__private_type_in_dep.snap @@ -6,4 +6,23 @@ expression: import dep ----- Completion content ----- -[] +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__unqualified_imported_type.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__unqualified_imported_type.snap index b71628bde..369f4cb99 100644 --- a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__unqualified_imported_type.snap +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__unqualified_imported_type.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 790 expression: "import dep.{type Zoo}\n\npub fn wibble(\n _: String,\n) -> Nil {\n Nil\n}\n" --- import dep.{type Zoo} @@ -12,323 +13,51 @@ pub fn wibble( ----- Completion content ----- -[ - CompletionItem { - label: "BitArray", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_BitArray", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Bool", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Bool", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Float", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Float", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Int", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Int", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "List", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_List", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Nil", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Nil", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Result", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_Result", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "String", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_String", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "UtfCodepoint", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "4_UtfCodepoint", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: None, - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "Zoo", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, - CompletionItem { - label: "dep.Zoo", - label_details: None, - kind: Some( - Class, - ), - detail: Some( - "Type", - ), - documentation: None, - deprecated: None, - preselect: None, - sort_text: Some( - "3_dep.Zoo", - ), - filter_text: None, - insert_text: None, - insert_text_format: None, - insert_text_mode: None, - text_edit: Some( - Edit( - TextEdit { - range: Range { - start: Position { - line: 3, - character: 0, - }, - end: Position { - line: 3, - character: 0, - }, - }, - new_text: "dep.Zoo", - }, - ), - ), - additional_text_edits: None, - command: None, - commit_characters: None, - data: None, - tags: None, - }, -] +BitArray + kind: Class + detail: Type + sort: 4_BitArray +Bool + kind: Class + detail: Type + sort: 4_Bool +Float + kind: Class + detail: Type + sort: 4_Float +Int + kind: Class + detail: Type + sort: 4_Int +List + kind: Class + detail: Type + sort: 4_List +Nil + kind: Class + detail: Type + sort: 4_Nil +Result + kind: Class + detail: Type + sort: 4_Result +String + kind: Class + detail: Type + sort: 4_String +UtfCodepoint + kind: Class + detail: Type + sort: 4_UtfCodepoint +Zoo + kind: Class + detail: Type + sort: 3_Zoo + edits: + [3:0-3:0]: "Zoo" +dep.Zoo + kind: Class + detail: Type + sort: 3_dep.Zoo + edits: + [3:0-3:0]: "dep.Zoo" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__variable_shadowing.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__variable_shadowing.snap new file mode 100644 index 000000000..a9c8549bf --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__completion__variable_shadowing.snap @@ -0,0 +1,48 @@ +--- +source: compiler-core/src/language_server/tests/completion.rs +assertion_line: 1729 +expression: "\npub fn main() {\n let x = 1\n let x = [1, 2]\n\n}\n" +--- +pub fn main() { + let x = 1 + let x = [1, 2] +| +} + + +----- Completion content ----- +Error + kind: Constructor + detail: gleam + sort: 4_Error +False + kind: EnumMember + detail: gleam + sort: 4_False +Nil + kind: EnumMember + detail: gleam + sort: 4_Nil +Ok + kind: Constructor + detail: gleam + sort: 4_Ok +True + kind: EnumMember + detail: gleam + sort: 4_True +main + kind: Function + detail: fn() -> List(Int) + sort: 2_main + desc: app + edits: + [4:0-4:0]: "main" +x + kind: Variable + detail: List(Int) + sort: 2_x + desc: app + docs: "A locally defined variable." + edits: + [4:0-4:0]: "x" diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap new file mode 100644 index 000000000..eeff68831 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap @@ -0,0 +1,26 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module +fn make_var() -> example_module.Wabble(example_module.Wibble(example_module.Wobble)) { + ↑ + example_module.Wabble(example_module.Wibble(example_module.Wobble(1))) +} + +----- Jumped to `build/packages/hex/src/example_module.gleam` + +pub type Wobble { +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Wobble(Int) +} + +pub type Wibble(a) { + Wibble(a) +} + +pub type Wabble(a) { + Wabble(a) +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_constants.snap new file mode 100644 index 000000000..768b204f1 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_constants.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module +fn main() { + example_module.my_num + ↑ +} + +----- Jumped to `build/packages/hex/src/example_module.gleam` +pub const my_num = 1 +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap new file mode 100644 index 000000000..ca785245b --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module +fn main() { + example_module.my_fn + ↑ +} + +----- Jumped to `build/packages/hex/src/example_module.gleam` +pub fn my_fn() { Nil } +↑▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_records.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_records.snap new file mode 100644 index 000000000..e22ca7f18 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_external_module_records.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module +fn main() { + example_module.Var1(1) + ↑ +} + +----- Jumped to `build/packages/hex/src/example_module.gleam` + +pub type Rec { + Var1(Int) + ↑▔▔▔▔▔▔▔▔ + Var2(Int, Int) +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import.snap new file mode 100644 index 000000000..b3255800a --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module + ↑ +fn main() { + example_module.my_num +} + +----- Jumped to `src/example_module.gleam` +pub const my_num = 1 +↑ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_aliased.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_aliased.snap new file mode 100644 index 000000000..088be7135 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_aliased.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module as example + ↑ +fn main() { + example.my_num +} + +----- Jumped to `src/example_module.gleam` +pub const my_num = 1 +↑ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap new file mode 100644 index 000000000..c78933b4a --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module.{type MyType} + ↑ +fn main() -> MyType { + 0 +} + +----- Jumped to `src/example_module.gleam` +pub type MyType = Int +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap new file mode 100644 index 000000000..51117c876 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module.{my_num} + ↑ +fn main() { + my_num +} + +----- Jumped to `src/example_module.gleam` +pub const my_num = 1 +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_imported_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_imported_module_constants.snap new file mode 100644 index 000000000..8d9af570a --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_imported_module_constants.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module +fn main() { + example_module.my_num + ↑ +} + +----- Jumped to `src/example_module.gleam` +pub const my_num = 1 +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_imported_module_records.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_imported_module_records.snap new file mode 100644 index 000000000..e09b35ce4 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_imported_module_records.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module +fn main() { + example_module.Var1(1) + ↑ +} + +----- Jumped to `src/example_module.gleam` + +pub type Rec { + Var1(Int) + ↑▔▔▔▔▔▔▔▔ + Var2(Int, Int) +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_local_variable.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_local_variable.snap new file mode 100644 index 000000000..2cd597845 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_local_variable.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +pub fn main() { + let x = 1 + x + ↑ +} + +----- Jumped to `src/app.gleam` + +pub fn main() { + let x = 1 + ↑ + x +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_module_function_calls.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_module_function_calls.snap new file mode 100644 index 000000000..616fdc4b9 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_module_function_calls.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module +fn main() { + example_module.my_fn + ↑ +} + +----- Jumped to `src/example_module.gleam` +pub fn my_fn() { Nil } +↑▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_of_external_function_in_same_module.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_of_external_function_in_same_module.snap new file mode 100644 index 000000000..6f67945ac --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_of_external_function_in_same_module.snap @@ -0,0 +1,23 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +@external(erlang, "wibble", "wobble") +fn external_function() -> Nil + +fn main() { + external_function() + ↑ +} + +----- Jumped to `src/app.gleam` + +@external(erlang, "wibble", "wobble") +fn external_function() -> Nil +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +fn main() { + external_function() +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap new file mode 100644 index 000000000..f4519ff95 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module +fn main() { + example_module.my_fn + ↑ +} + +----- Jumped to `dep/src/example_module.gleam` +pub fn my_fn() { Nil } +↑▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_constants.snap new file mode 100644 index 000000000..c441a0027 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_constants.snap @@ -0,0 +1,21 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +const x = 1 + +pub fn main() { + x + ↑ +} + +----- Jumped to `src/app.gleam` + +const x = 1 +↑▔▔▔▔▔▔ + +pub fn main() { + x +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_functions.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_functions.snap new file mode 100644 index 000000000..fb60e5f19 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_functions.snap @@ -0,0 +1,25 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +fn add_2(x) { + x + 2 +} + +pub fn main() { + add_2(1) + ↑ +} + +----- Jumped to `src/app.gleam` + +fn add_2(x) { +↑▔▔▔▔▔▔▔▔▔▔ + x + 2 +} + +pub fn main() { + add_2(1) +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_records.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_records.snap new file mode 100644 index 000000000..b0729f2b3 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_same_module_records.snap @@ -0,0 +1,29 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +pub type Rec { + Var1(Int) + Var2(Int, Int) +} + +pub fn main() { + let a = Var1(1) + ↑ + let b = Var2(2, 3) +} + +----- Jumped to `src/app.gleam` + +pub type Rec { + Var1(Int) + ↑▔▔▔▔▔▔▔▔ + Var2(Int, Int) +} + +pub fn main() { + let a = Var1(1) + let b = Var2(2, 3) +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type.snap new file mode 100644 index 000000000..52dd9c73e --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type.snap @@ -0,0 +1,27 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +pub type Rec { + Var1(Int) + Var2(Int, Int) +} + +pub fn make_var() -> Rec { + ↑ + Var1(1) +} + +----- Jumped to `src/app.gleam` + +pub type Rec { +↑▔▔▔▔▔▔▔▔▔▔▔ + Var1(Int) + Var2(Int, Int) +} + +pub fn make_var() -> Rec { + Var1(1) +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type_in_module.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type_in_module.snap new file mode 100644 index 000000000..82a7ed298 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type_in_module.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module +fn make_var() -> example_module.Rec { + ↑ + example_module.Var1(1) +} + +----- Jumped to `build/packages/hex/src/example_module.gleam` + +pub type Rec { +↑▔▔▔▔▔▔▔▔▔▔▔ + Var1(Int) + Var2(Int, Int) +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap new file mode 100644 index 000000000..3b662604d --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module +fn make_var() -> example_module.Rec { + ↑ + example_module.Var1(1) +} + +----- Jumped to `dep/src/example_module.gleam` + +pub type Rec { +↑▔▔▔▔▔▔▔▔▔▔▔ + Var1(Int) + Var2(Int, Int) +} diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_function.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_function.snap new file mode 100644 index 000000000..e64b711e8 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_function.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import wibble.{wobble} +fn main() { + wobble() + ↑ +} + +----- Jumped to `src/wibble.gleam` +pub fn wobble() {} +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap new file mode 100644 index 000000000..c66c63d39 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module.{my_num} +fn main() { + my_num + ↑ +} + +----- Jumped to `src/example_module.gleam` +pub const my_num = 1 +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap new file mode 100644 index 000000000..04bc4e937 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/glistix_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +import example_module.{Var1} +fn main() { + Var1(1) + ↑ +} + +----- Jumped to `src/example_module.gleam` + +pub type Rec { + Var1(Int) + ↑▔▔▔▔▔▔▔▔ + Var2(Int, Int) +} diff --git a/compiler-core/src/lib.rs b/compiler-core/src/lib.rs index 857ef5367..dd1517e5c 100644 --- a/compiler-core/src/lib.rs +++ b/compiler-core/src/lib.rs @@ -102,6 +102,6 @@ const GLEAM_CORE_PACKAGE_NAME: &str = ""; const STDLIB_PACKAGE_NAME: &str = "gleam_stdlib"; mod schema_capnp { - #![allow(dead_code, unused_qualifications)] + #![allow(dead_code, unused_qualifications, clippy::all)] include!("../generated/schema_capnp.rs"); } diff --git a/compiler-core/src/metadata/module_decoder.rs b/compiler-core/src/metadata/module_decoder.rs index 6ec5a948b..598e2795a 100755 --- a/compiler-core/src/metadata/module_decoder.rs +++ b/compiler-core/src/metadata/module_decoder.rs @@ -78,10 +78,10 @@ impl ModuleDecoder { type_variants_constructors ), accessors: read_hashmap!(reader.get_accessors()?, self, accessors_map), - unused_imports: read_vec!(reader.get_unused_imports()?, self, src_span), line_numbers: self.line_numbers(&reader.get_line_numbers()?)?, src_path: reader.get_src_path()?.into(), warnings: vec![], + minimum_required_version: self.version(&reader.get_required_version()?), }) } @@ -97,11 +97,11 @@ impl ModuleDecoder { }, }; Ok(TypeConstructor { - publicity: self.publicity(reader.get_publicity()?), + publicity: self.publicity(reader.get_publicity()?)?, origin: self.src_span(&reader.get_origin()?)?, module: reader.get_module()?.into(), parameters: read_vec!(reader.get_parameters()?, self, type_), - typ: type_, + type_, deprecation, documentation: self.optional_string(reader.get_documentation()?), }) @@ -212,7 +212,7 @@ impl ModuleDecoder { ) -> Result { let type_ = self.type_(&reader.get_type()?)?; let variant = self.value_constructor_variant(&reader.get_variant()?)?; - let publicity = self.publicity(reader.get_publicity()?); + let publicity = self.publicity(reader.get_publicity()?)?; let deprecation = match reader.get_deprecated()? { "" => Deprecation::NotDeprecated, message => Deprecation::Deprecated { @@ -227,11 +227,18 @@ impl ModuleDecoder { }) } - fn publicity(&self, publicity: crate::schema_capnp::Publicity) -> Publicity { - match publicity { - schema::Publicity::Public => Publicity::Public, - schema::Publicity::Private => Publicity::Private, - schema::Publicity::Internal => Publicity::Internal, + fn publicity(&self, reader: publicity::Reader<'_>) -> Result { + match reader.which()? { + publicity::Which::Public(()) => Ok(Publicity::Public), + publicity::Which::Private(()) => Ok(Publicity::Private), + publicity::Which::Internal(reader) => match reader?.which()? { + option::Which::None(()) => Ok(Publicity::Internal { + attribute_location: None, + }), + option::Which::Some(reader) => Ok(Publicity::Internal { + attribute_location: Some(self.src_span(&reader?)?), + }), + }, } } @@ -286,12 +293,12 @@ impl ModuleDecoder { Ok(Constant::List { location: Default::default(), elements: read_vec!(reader.get_elements()?, self, constant), - typ: type_, + type_, }) } fn constant_record(&mut self, reader: &constant::record::Reader<'_>) -> Result { - let type_ = self.type_(&reader.get_typ()?)?; + let type_ = self.type_(&reader.get_type()?)?; let tag = reader.get_tag()?.into(); let args = read_vec!(reader.get_args()?, self, constant_call_arg); Ok(Constant::Record { @@ -300,7 +307,7 @@ impl ModuleDecoder { name: Default::default(), args, tag, - typ: type_, + type_, field_map: None, }) } @@ -328,7 +335,7 @@ impl ModuleDecoder { } fn constant_var(&mut self, reader: &constant::var::Reader<'_>) -> Result { - let type_ = self.type_(&reader.get_typ()?)?; + let type_ = self.type_(&reader.get_type()?)?; let module = match reader.get_module()? { "" => None, module_str => Some(module_str), @@ -337,10 +344,10 @@ impl ModuleDecoder { let constructor = self.value_constructor(&reader.get_constructor()?)?; Ok(Constant::Var { location: Default::default(), - module: module.map(EcoString::from), + module: module.map(|module| (EcoString::from(module), Default::default())), name: name.into(), constructor: Some(Box::from(constructor)), - typ: type_, + type_, }) } @@ -482,6 +489,9 @@ impl ModuleDecoder { location: self.src_span(&reader.get_location()?)?, documentation: self.optional_string(reader.get_documentation()?), implementations: self.implementations(reader.get_implementations()?), + external_erlang: self.optional_external(reader.get_external_erlang()?)?, + external_javascript: self.optional_external(reader.get_external_javascript()?)?, + external_nix: self.optional_external(reader.get_external_nix()?)?, }) } @@ -557,4 +567,23 @@ impl ModuleDecoder { line_starts: read_vec!(reader.get_line_starts()?, self, line_starts), }) } + + fn version(&self, reader: &version::Reader<'_>) -> hexpm::version::Version { + hexpm::version::Version::new(reader.get_major(), reader.get_minor(), reader.get_patch()) + } + + fn optional_external( + &self, + reader: option::Reader<'_, external::Owned>, + ) -> Result> { + match reader.which()? { + option::Which::None(()) => Ok(None), + option::Which::Some(reader) => { + let reader = reader?; + let module = EcoString::from(reader.get_module()?); + let function = EcoString::from(reader.get_function()?); + Ok(Some((module, function))) + } + } + } } diff --git a/compiler-core/src/metadata/module_encoder.rs b/compiler-core/src/metadata/module_encoder.rs index b896f2884..0aabe365c 100644 --- a/compiler-core/src/metadata/module_encoder.rs +++ b/compiler-core/src/metadata/module_encoder.rs @@ -46,8 +46,8 @@ impl<'a> ModuleEncoder<'a> { self.set_module_values(&mut module); self.set_module_accessors(&mut module); self.set_module_types_constructors(&mut module); - self.set_unused_imports(&mut module); self.set_line_numbers(&mut module); + self.set_version(&mut module); capnp::serialize_packed::write_message(&mut buffer, &message).expect("capnp encode"); Ok(buffer) @@ -63,16 +63,6 @@ impl<'a> ModuleEncoder<'a> { } } - fn set_unused_imports(&mut self, module: &mut module::Builder<'_>) { - let mut unused_imports = module - .reborrow() - .init_unused_imports(self.data.unused_imports.len() as u32); - for (i, span) in self.data.unused_imports.iter().enumerate() { - let unused_import = unused_imports.reborrow().get(i as u32); - self.build_src_span(unused_import, *span) - } - } - fn set_module_accessors(&mut self, module: &mut module::Builder<'_>) { tracing::trace!("Writing module metadata accessors"); let mut builder = module @@ -161,6 +151,13 @@ impl<'a> ModuleEncoder<'a> { } } + fn set_version(&mut self, module: &mut module::Builder<'_>) { + let mut version = module.reborrow().init_required_version(); + version.set_major(self.data.minimum_required_version.major); + version.set_minor(self.data.minimum_required_version.minor); + version.set_patch(self.data.minimum_required_version.patch); + } + fn build_type_constructor( &mut self, mut builder: type_constructor::Builder<'_>, @@ -171,9 +168,9 @@ impl<'a> ModuleEncoder<'a> { Deprecation::NotDeprecated => "", Deprecation::Deprecated { message } => message, }); - builder.set_publicity(self.publicity(constructor.publicity)); + self.build_publicity(builder.reborrow().init_publicity(), constructor.publicity); let type_builder = builder.reborrow().init_type(); - self.build_type(type_builder, &constructor.typ); + self.build_type(type_builder, &constructor.type_); self.build_types( builder .reborrow() @@ -222,16 +219,29 @@ impl<'a> ModuleEncoder<'a> { Deprecation::NotDeprecated => "", Deprecation::Deprecated { message } => message, }); - builder.set_publicity(self.publicity(constructor.publicity)); + + self.build_publicity(builder.reborrow().init_publicity(), constructor.publicity); self.build_type(builder.reborrow().init_type(), &constructor.type_); self.build_value_constructor_variant(builder.init_variant(), &constructor.variant); } - fn publicity(&self, publicity: Publicity) -> crate::schema_capnp::Publicity { + fn build_publicity(&mut self, mut builder: publicity::Builder<'_>, publicity: Publicity) { match publicity { - Publicity::Public => crate::schema_capnp::Publicity::Public, - Publicity::Private => crate::schema_capnp::Publicity::Private, - Publicity::Internal => crate::schema_capnp::Publicity::Internal, + Publicity::Public => builder.set_public(()), + Publicity::Private => builder.set_private(()), + Publicity::Internal { + attribute_location: None, + } => { + let mut builder = builder.init_internal(); + builder.set_none(()); + } + Publicity::Internal { + attribute_location: Some(location), + } => { + let builder = builder.init_internal(); + let builder = builder.init_some(); + self.build_src_span(builder, location); + } } } @@ -298,12 +308,21 @@ impl<'a> ModuleEncoder<'a> { location, documentation: doc, implementations, + external_erlang, + external_javascript, + external_nix, } => { let mut builder = builder.init_module_fn(); builder.set_name(name); builder.set_module(module); builder.set_arity(*arity as u16); builder.set_documentation(doc.as_ref().map(EcoString::as_str).unwrap_or_default()); + self.build_external(builder.reborrow().init_external_erlang(), external_erlang); + self.build_external( + builder.reborrow().init_external_javascript(), + external_javascript, + ); + self.build_external(builder.reborrow().init_external_nix(), external_nix); self.build_optional_field_map(builder.reborrow().init_field_map(), field_map); self.build_src_span(builder.reborrow().init_location(), *location); self.build_implementations(builder.init_implementations(), *implementations); @@ -342,13 +361,15 @@ impl<'a> ModuleEncoder<'a> { self.build_constants(builder.init_tuple(elements.len() as u32), elements) } - Constant::List { elements, typ, .. } => { + Constant::List { + elements, type_, .. + } => { let mut builder = builder.init_list(); self.build_constants( builder.reborrow().init_elements(elements.len() as u32), elements, ); - self.build_type(builder.init_type(), typ); + self.build_type(builder.init_type(), type_); } Constant::BitArray { segments, .. } => { @@ -358,7 +379,9 @@ impl<'a> ModuleEncoder<'a> { } } - Constant::Record { args, tag, typ, .. } => { + Constant::Record { + args, tag, type_, .. + } => { let mut builder = builder.init_record(); { let mut builder = builder.reborrow().init_args(args.len() as u32); @@ -367,23 +390,23 @@ impl<'a> ModuleEncoder<'a> { } } builder.reborrow().set_tag(tag); - self.build_type(builder.reborrow().init_typ(), typ); + self.build_type(builder.reborrow().init_type(), type_); } Constant::Var { module, name, - typ, + type_, constructor, .. } => { let mut builder = builder.init_var(); match module { - Some(name) => builder.set_module(name), + Some((name, _)) => builder.set_module(name), None => builder.set_module(""), }; builder.set_name(name); - self.build_type(builder.reborrow().init_typ(), typ); + self.build_type(builder.reborrow().init_type(), type_); self.build_value_constructor( builder.reborrow().init_constructor(), constructor @@ -496,8 +519,8 @@ impl<'a> ModuleEncoder<'a> { elems, ), - Type::Var { type_: typ } => match typ.borrow().deref() { - TypeVar::Link { type_: typ } => self.build_type(builder, typ), + Type::Var { type_ } => match type_.borrow().deref() { + TypeVar::Link { type_ } => self.build_type(builder, type_), TypeVar::Unbound { id, .. } | TypeVar::Generic { id } => { self.build_type_var(builder.init_var(), *id) } @@ -545,4 +568,19 @@ impl<'a> ModuleEncoder<'a> { builder.set_can_run_on_javascript(implementations.can_run_on_javascript); builder.set_can_run_on_nix(implementations.can_run_on_nix); } + + fn build_external( + &self, + mut builder: option::Builder<'_, external::Owned>, + external: &Option<(EcoString, EcoString)>, + ) { + match external { + None => builder.set_none(()), + Some((module, function)) => { + let mut builder = builder.init_some(); + builder.set_module(module); + builder.set_function(function); + } + } + } } diff --git a/compiler-core/src/metadata/tests.rs b/compiler-core/src/metadata/tests.rs index 1ca9aee10..60844af20 100644 --- a/compiler-core/src/metadata/tests.rs +++ b/compiler-core/src/metadata/tests.rs @@ -1,3 +1,4 @@ +use hexpm::version::Version; use rand::Rng; use type_::{AccessorsMap, FieldMap, RecordAccessor}; @@ -37,7 +38,6 @@ fn constant_module(constant: TypedConstant) -> ModuleInterface { name: "a".into(), types: HashMap::new(), types_value_constructors: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), values: [( "one".into(), @@ -65,6 +65,7 @@ fn constant_module(constant: TypedConstant) -> ModuleInterface { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), } } @@ -94,10 +95,10 @@ fn empty_module() { types: HashMap::new(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); } @@ -113,7 +114,6 @@ fn with_line_numbers() { types: HashMap::new(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new( "const a = 1 @@ -121,6 +121,7 @@ fn with_line_numbers() { const c = 3", ), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); } @@ -136,7 +137,7 @@ fn module_with_private_type() { types: [( "ListIntType".into(), TypeConstructor { - typ: type_::list(type_::int()), + type_: type_::list(type_::int()), publicity: Publicity::Private, origin: Default::default(), module: "the/module".into(), @@ -148,32 +149,10 @@ fn module_with_private_type() { .into(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), - }; - assert_eq!(roundtrip(&module), module); -} - -#[test] -fn module_with_unused_import() { - let module = ModuleInterface { - warnings: vec![], - is_internal: false, - package: "some_package".into(), - origin: Origin::Src, - name: "a".into(), - types: HashMap::new(), - types_value_constructors: HashMap::new(), - unused_imports: vec![ - SrcSpan { start: 0, end: 10 }, - SrcSpan { start: 13, end: 42 }, - ], - accessors: HashMap::new(), - values: HashMap::new(), - line_numbers: LineNumbers::new(""), - src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); } @@ -189,7 +168,7 @@ fn module_with_app_type() { types: [( "ListIntType".into(), TypeConstructor { - typ: type_::list(type_::int()), + type_: type_::list(type_::int()), publicity: Publicity::Public, origin: Default::default(), module: "the/module".into(), @@ -201,10 +180,10 @@ fn module_with_app_type() { .into(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); } @@ -220,7 +199,7 @@ fn module_with_fn_type() { types: [( "FnType".into(), TypeConstructor { - typ: type_::fn_(vec![type_::nil(), type_::float()], type_::int()), + type_: type_::fn_(vec![type_::nil(), type_::float()], type_::int()), publicity: Publicity::Public, origin: Default::default(), module: "the/module".into(), @@ -232,10 +211,10 @@ fn module_with_fn_type() { .into(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); } @@ -251,7 +230,7 @@ fn module_with_tuple_type() { types: [( "TupleType".into(), TypeConstructor { - typ: type_::tuple(vec![type_::nil(), type_::float(), type_::int()]), + type_: type_::tuple(vec![type_::nil(), type_::float(), type_::int()]), publicity: Publicity::Public, origin: Default::default(), module: "the/module".into(), @@ -263,10 +242,10 @@ fn module_with_tuple_type() { .into(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); } @@ -288,7 +267,7 @@ fn module_with_generic_type() { types: [( "TupleType".into(), TypeConstructor { - typ: type_::tuple(vec![t1.clone(), t1.clone(), t2.clone()]), + type_: type_::tuple(vec![t1.clone(), t1.clone(), t2.clone()]), publicity: Publicity::Public, origin: Default::default(), module: "the/module".into(), @@ -300,10 +279,10 @@ fn module_with_generic_type() { .into(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), } } @@ -325,7 +304,7 @@ fn module_with_type_links() { types: [( "SomeType".into(), TypeConstructor { - typ: type_, + type_, publicity: Publicity::Public, origin: Default::default(), module: "a".into(), @@ -337,10 +316,10 @@ fn module_with_type_links() { .into(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), } } @@ -362,7 +341,7 @@ fn module_with_type_constructor_documentation() { types: [( "SomeType".into(), TypeConstructor { - typ: type_, + type_, publicity: Publicity::Public, origin: Default::default(), module: "a".into(), @@ -374,10 +353,10 @@ fn module_with_type_constructor_documentation() { .into(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), } } @@ -399,7 +378,7 @@ fn module_with_type_constructor_origin() { types: [( "SomeType".into(), TypeConstructor { - typ: type_, + type_, publicity: Publicity::Public, origin: SrcSpan { start: 535, @@ -414,10 +393,10 @@ fn module_with_type_constructor_origin() { .into(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), } } @@ -444,11 +423,11 @@ fn module_type_to_constructors_mapping() { }, )] .into(), - unused_imports: Default::default(), accessors: HashMap::new(), values: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); @@ -463,7 +442,6 @@ fn module_fn_value() { origin: Origin::Src, name: "a".into(), types: HashMap::new(), - unused_imports: Vec::new(), types_value_constructors: HashMap::new(), accessors: HashMap::new(), values: [( @@ -482,6 +460,9 @@ fn module_fn_value() { start: 535, end: 1100, }, + external_erlang: None, + external_javascript: None, + external_nix: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -497,6 +478,7 @@ fn module_fn_value() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); } @@ -511,7 +493,6 @@ fn deprecated_module_fn_value() { name: "a".into(), types: HashMap::new(), types_value_constructors: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), values: [( "one".into(), @@ -531,6 +512,9 @@ fn deprecated_module_fn_value() { start: 535, end: 1100, }, + external_erlang: None, + external_javascript: None, + external_nix: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -546,6 +530,7 @@ fn deprecated_module_fn_value() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); } @@ -559,7 +544,6 @@ fn private_module_fn_value() { origin: Origin::Src, name: "a".into(), types: HashMap::new(), - unused_imports: Vec::new(), types_value_constructors: HashMap::new(), accessors: HashMap::new(), values: [( @@ -578,6 +562,9 @@ fn private_module_fn_value() { start: 535, end: 1100, }, + external_erlang: None, + external_javascript: None, + external_nix: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -593,6 +580,7 @@ fn private_module_fn_value() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); @@ -609,7 +597,6 @@ fn module_fn_value_regression() { name: "a/b/c".into(), types: HashMap::new(), types_value_constructors: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), values: [( "one".into(), @@ -627,6 +614,9 @@ fn module_fn_value_regression() { start: 52, end: 1100, }, + external_erlang: None, + external_javascript: None, + external_nix: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -642,6 +632,7 @@ fn module_fn_value_regression() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); @@ -657,7 +648,6 @@ fn module_fn_value_with_field_map() { name: "a".into(), types: HashMap::new(), types_value_constructors: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), values: [( "one".into(), @@ -672,6 +662,9 @@ fn module_fn_value_with_field_map() { arity: 20, fields: [("ok".into(), 5), ("ko".into(), 7)].into(), }), + external_erlang: None, + external_javascript: None, + external_nix: None, module: "a".into(), arity: 5, location: SrcSpan { start: 2, end: 11 }, @@ -690,6 +683,7 @@ fn module_fn_value_with_field_map() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); @@ -707,7 +701,6 @@ fn record_value() { name: "a".into(), types: HashMap::new(), types_value_constructors: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), values: [( "one".into(), @@ -733,6 +726,7 @@ fn record_value() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); @@ -750,7 +744,6 @@ fn record_value_with_field_map() { name: "a".into(), types: HashMap::new(), types_value_constructors: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), values: [( "one".into(), @@ -779,6 +772,7 @@ fn record_value_with_field_map() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); @@ -795,7 +789,6 @@ fn accessors() { types: HashMap::new(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: [ ( "one".into(), @@ -843,6 +836,7 @@ fn accessors() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); @@ -914,7 +908,7 @@ fn constant_tuple() { fn constant_list() { let module = constant_module(Constant::List { location: Default::default(), - typ: type_::int(), + type_: type_::int(), elements: vec![ Constant::Int { location: Default::default(), @@ -961,7 +955,7 @@ fn constant_record() { }, ], tag: "thetag".into(), - typ: type_::int(), + type_: type_::int(), field_map: None, }); @@ -979,7 +973,7 @@ fn constant_var() { location: Default::default(), module: None, name: "one_original".into(), - typ: type_::int(), + type_: type_::int(), constructor: Some(Box::from(ValueConstructor { publicity: Publicity::Public, deprecation: Deprecation::NotDeprecated, @@ -1010,7 +1004,6 @@ fn constant_var() { name: "a".into(), types: HashMap::new(), types_value_constructors: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), values: [ ( @@ -1063,6 +1056,7 @@ fn constant_var() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); @@ -1235,7 +1229,7 @@ fn deprecated_type() { types: [( "ListIntType".into(), TypeConstructor { - typ: type_::list(type_::int()), + type_: type_::list(type_::int()), publicity: Publicity::Public, origin: Default::default(), module: "the/module".into(), @@ -1249,10 +1243,10 @@ fn deprecated_type() { .into(), types_value_constructors: HashMap::new(), values: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); } @@ -1267,7 +1261,6 @@ fn module_fn_value_with_external_implementations() { name: "a/b/c".into(), types: HashMap::new(), types_value_constructors: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), values: [( "one".into(), @@ -1285,6 +1278,9 @@ fn module_fn_value_with_external_implementations() { start: 52, end: 1100, }, + external_erlang: Some(("wibble".into(), "wobble".into())), + external_javascript: Some(("wobble".into(), "wibble".into())), + external_nix: None, implementations: Implementations { gleam: false, uses_erlang_externals: true, @@ -1300,6 +1296,7 @@ fn module_fn_value_with_external_implementations() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); @@ -1315,12 +1312,69 @@ fn internal_module_fn() { name: "a/b/c".into(), types: HashMap::new(), types_value_constructors: HashMap::new(), - unused_imports: Vec::new(), accessors: HashMap::new(), values: [( "one".into(), ValueConstructor { - publicity: Publicity::Internal, + publicity: Publicity::Internal { + attribute_location: None, + }, + deprecation: Deprecation::NotDeprecated, + type_: type_::int(), + variant: ValueConstructorVariant::ModuleFn { + documentation: Some("wabble!".into()), + name: "one".into(), + field_map: None, + module: "a".into(), + arity: 5, + location: SrcSpan { + start: 52, + end: 1100, + }, + external_erlang: Some(("wibble".into(), "wobble".into())), + external_javascript: Some(("wobble".into(), "wibble".into())), + external_nix: None, + implementations: Implementations { + gleam: false, + uses_erlang_externals: true, + uses_javascript_externals: true, + uses_nix_externals: false, + can_run_on_erlang: true, + can_run_on_javascript: true, + can_run_on_nix: false, + }, + }, + }, + )] + .into(), + line_numbers: LineNumbers::new(""), + src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), + }; + + assert_eq!(roundtrip(&module), module); +} + +#[test] +fn internal_annotated_module_fn() { + let module = ModuleInterface { + warnings: vec![], + is_internal: false, + package: "some_package".into(), + origin: Origin::Src, + name: "a/b/c".into(), + types: HashMap::new(), + types_value_constructors: HashMap::new(), + accessors: HashMap::new(), + values: [( + "one".into(), + ValueConstructor { + publicity: Publicity::Internal { + attribute_location: Some(SrcSpan { + start: 11, + end: 111, + }), + }, deprecation: Deprecation::NotDeprecated, type_: type_::int(), variant: ValueConstructorVariant::ModuleFn { @@ -1333,6 +1387,9 @@ fn internal_module_fn() { start: 52, end: 1100, }, + external_erlang: Some(("wibble".into(), "wobble".into())), + external_javascript: Some(("wobble".into(), "wibble".into())), + external_nix: None, implementations: Implementations { gleam: false, uses_erlang_externals: true, @@ -1348,6 +1405,7 @@ fn internal_module_fn() { .into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; assert_eq!(roundtrip(&module), module); @@ -1383,11 +1441,11 @@ fn type_variable_ids_in_constructors_are_shared() { }], }, )]), - unused_imports: Vec::new(), accessors: HashMap::new(), values: [].into(), line_numbers: LineNumbers::new(""), src_path: "some_path".into(), + minimum_required_version: Version::new(0, 1, 0), }; let expected = HashMap::from([( diff --git a/compiler-core/src/nix.rs b/compiler-core/src/nix.rs index 0f022154d..46aafa649 100644 --- a/compiler-core/src/nix.rs +++ b/compiler-core/src/nix.rs @@ -421,7 +421,7 @@ impl<'module> Generator<'module> { Definition::Function(Function { name: Some((_, name)), publicity, - external_nix: Some((module, function)), + external_nix: Some((module, function, _location)), .. }) => { self.register_external_function( diff --git a/compiler-core/src/nix/expression.rs b/compiler-core/src/nix/expression.rs index 213b07338..99b1f0b9d 100644 --- a/compiler-core/src/nix/expression.rs +++ b/compiler-core/src/nix/expression.rs @@ -1,7 +1,7 @@ use crate::ast::{ - Arg, BinOp, BitArrayOption, BitArraySegment, CallArg, Constant, SrcSpan, Statement, TypedArg, - TypedAssignment, TypedClause, TypedConstant, TypedExpr, TypedExprBitArraySegment, TypedModule, - TypedPattern, TypedRecordUpdateArg, TypedStatement, + Arg, BinOp, BitArrayOption, CallArg, Constant, SrcSpan, Statement, TypedArg, TypedAssignment, + TypedClause, TypedConstant, TypedConstantBitArraySegment, TypedExpr, TypedExprBitArraySegment, + TypedModule, TypedPattern, TypedRecordUpdateArg, TypedStatement, }; use crate::docvec; use crate::line_numbers::LineNumbers; @@ -440,7 +440,9 @@ impl<'module> Generator<'module> { constant_expression(self.tracker, literal) } ValueConstructorVariant::Record { .. } => { - Ok(self.record_constructor(constructor.type_.clone(), None, name)) + let type_ = constructor.type_.clone(); + let tracker = &mut self.tracker; + Ok(record_constructor(type_, None, name, tracker)) } ValueConstructorVariant::ModuleFn { .. } | ValueConstructorVariant::ModuleConstant { .. } @@ -795,7 +797,9 @@ impl Generator<'_> { fn todo<'a>(&mut self, location: &'a SrcSpan, message: Option<&'a TypedExpr>) -> Output<'a> { let message = match message { Some(m) => self.wrap_child_expression(m)?, - None => "\"This has not yet been implemented\"".to_doc(), + None => { + "\"`todo` expression evaluated. This code has not yet been implemented.\"".to_doc() + } }; Ok(self.throw_error("todo", &message, *location, vec![])) @@ -804,7 +808,7 @@ impl Generator<'_> { fn panic<'a>(&mut self, location: &'a SrcSpan, message: Option<&'a TypedExpr>) -> Output<'a> { let message = match message { Some(m) => self.wrap_child_expression(m)?, - None => "\"panic expression evaluated\"".to_doc(), + None => "\"`panic` expression evaluated.\"".to_doc(), }; Ok(self.throw_error("panic", &message, *location, vec![])) @@ -929,7 +933,8 @@ impl Generator<'_> { should_be_equal: bool, ) -> Output<'a> { // Nix's equality is always structural. - return self.print_bin_op(left, right, if should_be_equal { "==" } else { "!=" }); + self.print_bin_op(left, right, if should_be_equal { "==" } else { "!=" }) + // Inherited code (equality was not always structural): // if is_nix_scalar(left.type_()) { // } // Other types must be compared using structural equality @@ -988,35 +993,6 @@ impl Generator<'_> { Ok(docvec![record, " // ", set]) } - fn record_constructor<'a>( - &mut self, - type_: Arc, - qualifier: Option<&'a str>, - name: &'a str, - ) -> Document<'a> { - if qualifier.is_none() && type_.is_result_constructor() { - if name == "Ok" { - self.tracker.ok_used = true; - } else if name == "Error" { - self.tracker.error_used = true; - } - } - if type_.is_bool() && name == "True" { - "true".to_doc() - } else if type_.is_bool() { - "false".to_doc() - } else if type_.is_nil() { - "null".to_doc() - } else { - // Use the record constructor directly. - // No need to escape the name as it must start with an uppercase letter. - match qualifier { - Some(module) => docvec![module_var_name_doc(module), ".", name], - None => name.to_doc(), - } - } - } - fn module_select<'a>( &mut self, module: &'a str, @@ -1036,7 +1012,7 @@ impl Generator<'_> { } ModuleValueConstructor::Record { name, type_, .. } => { - self.record_constructor(type_.clone(), Some(module), name) + record_constructor(type_.clone(), Some(module), name, self.tracker) } } } @@ -1057,7 +1033,7 @@ impl Generator<'_> { let size_int = match *size.clone() { TypedExpr::Int { location: _, - typ: _, + type_: _, value, } => value.parse().unwrap_or(0), _ => 0, @@ -1190,8 +1166,8 @@ impl Generator<'_> { subject: Document<'a>, ) -> Document<'a> { self.throw_error( - "assignment_no_match", - &"\"Assignment pattern did not match\"".to_doc(), + "let_assert", + &"\"Pattern match failed, no pattern matched the value.\"".to_doc(), location, [("value", subject)], ) @@ -1218,23 +1194,23 @@ pub(crate) fn guard_constant_expression<'a>( .map(|e| wrap_child_guard_constant_expression(assignments, tracker, e)), ) } - Constant::Record { typ, name, .. } if typ.is_bool() && name == "True" => { + Constant::Record { type_, name, .. } if type_.is_bool() && name == "True" => { Ok("true".to_doc()) } - Constant::Record { typ, name, .. } if typ.is_bool() && name == "False" => { + Constant::Record { type_, name, .. } if type_.is_bool() && name == "False" => { Ok("false".to_doc()) } - Constant::Record { typ, .. } if typ.is_nil() => Ok("null".to_doc()), + Constant::Record { type_, .. } if type_.is_nil() => Ok("null".to_doc()), Constant::Record { args, module, name, tag, - typ, + type_, .. } => { - if typ.is_result() { + if type_.is_result() { if tag == "Ok" { tracker.ok_used = true; } else { @@ -1245,7 +1221,11 @@ pub(crate) fn guard_constant_expression<'a>( .iter() .map(|arg| wrap_child_guard_constant_expression(assignments, tracker, &arg.value)) .try_collect()?; - Ok(construct_record(module.as_deref(), name, field_values)) + Ok(construct_record( + module.as_ref().map(|(module, _)| module.as_str()), + name, + field_values, + )) } Constant::BitArray { segments, .. } => { @@ -1291,35 +1271,49 @@ pub(crate) fn constant_expression<'a>( ) } - Constant::Record { typ, name, .. } if typ.is_bool() && name == "True" => { + Constant::Record { type_, name, .. } if type_.is_bool() && name == "True" => { Ok("true".to_doc()) } - Constant::Record { typ, name, .. } if typ.is_bool() && name == "False" => { + Constant::Record { type_, name, .. } if type_.is_bool() && name == "False" => { Ok("false".to_doc()) } - Constant::Record { typ, .. } if typ.is_nil() => Ok("null".to_doc()), + Constant::Record { type_, .. } if type_.is_nil() => Ok("null".to_doc()), Constant::Record { args, module, name, tag, - typ, + type_, .. } => { - if typ.is_result() { + if type_.is_result() { if tag == "Ok" { tracker.ok_used = true; } else { tracker.error_used = true; } } + + // If there's no arguments and the type is a function that takes + // arguments then this is the constructor being referenced, not the + // function being called. + if let Some(arity) = type_.fn_arity() { + if args.is_empty() && arity != 0 { + return Ok(record_constructor(type_.clone(), None, name, tracker)); + } + } + let field_values = args .iter() .map(|arg| wrap_child_constant_expression(tracker, &arg.value)) .try_collect()?; - Ok(construct_record(module.as_deref(), name, field_values)) + Ok(construct_record( + module.as_ref().map(|(module, _)| module.as_str()), + name, + field_values, + )) } Constant::BitArray { segments, .. } => { @@ -1329,7 +1323,7 @@ pub(crate) fn constant_expression<'a>( Constant::Var { name, module, .. } => Ok({ match module { None => maybe_escape_identifier_doc(name), - Some(module) => docvec![ + Some((module, _)) => docvec![ module_var_name_doc(module), ".", maybe_escape_identifier_doc(name) @@ -1590,7 +1584,7 @@ pub fn list<'a, Elements: IntoIterator>>(elements: Elements) - fn constant_bit_array<'a>( tracker: &mut UsageTracker, - segments: &'a [BitArraySegment>], + segments: &'a [TypedConstantBitArraySegment], mut wrap_child_constant_expr_fun: impl FnMut(&mut UsageTracker, &'a TypedConstant) -> Output<'a>, ) -> Output<'a> { tracker.bit_array_literal_used = true; @@ -1724,3 +1718,33 @@ fn owned_local_var<'a>(name: EcoString, next: usize) -> Document<'a> { n => Document::String(format!("{name}'{n}")), } } + +/// A record constructor: `Ok`, `Some`, `True`, `Nil` +fn record_constructor<'a>( + type_: Arc, + qualifier: Option<&'a str>, + name: &'a str, + tracker: &mut UsageTracker, +) -> Document<'a> { + if qualifier.is_none() && type_.is_result_constructor() { + if name == "Ok" { + tracker.ok_used = true; + } else if name == "Error" { + tracker.error_used = true; + } + } + if type_.is_bool() && name == "True" { + "true".to_doc() + } else if type_.is_bool() { + "false".to_doc() + } else if type_.is_nil() { + "null".to_doc() + } else { + // Use the record constructor directly. + // No need to escape the name as it must start with an uppercase letter. + match qualifier { + Some(module) => docvec![module_var_name_doc(module), ".", name], + None => name.to_doc(), + } + } +} diff --git a/compiler-core/src/nix/pattern.rs b/compiler-core/src/nix/pattern.rs index efd0d95dd..08c5ce8be 100644 --- a/compiler-core/src/nix/pattern.rs +++ b/compiler-core/src/nix/pattern.rs @@ -838,7 +838,7 @@ pub struct CompiledPattern<'a> { pub assignments: Vec>, } -impl<'a> CompiledPattern<'a> { +impl CompiledPattern<'_> { pub fn has_assignments(&self) -> bool { !self.assignments.is_empty() } diff --git a/compiler-core/src/nix/tests.rs b/compiler-core/src/nix/tests.rs index 4ee07a603..c98946037 100644 --- a/compiler-core/src/nix/tests.rs +++ b/compiler-core/src/nix/tests.rs @@ -41,7 +41,7 @@ pub static CURRENT_PACKAGE: &str = "thepackage"; macro_rules! assert_nix_with_multiple_imports { ($(($name:literal, $module_src:literal)),+; $src:literal) => { let output = - $crate::nix::tests::compile_nix($src, vec![$((CURRENT_PACKAGE, $name, $module_src)),*]); + $crate::nix::tests::compile_nix($src, vec![$((CURRENT_PACKAGE, $name, $module_src)),*]).expect("compilation failed"); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }; } @@ -50,27 +50,37 @@ macro_rules! assert_nix_with_multiple_imports { macro_rules! assert_nix { (($dep_package:expr, $dep_name:expr, $dep_src:expr), $src:expr $(,)?) => {{ let output = - $crate::nix::tests::compile_nix($src, vec![($dep_package, $dep_name, $dep_src)]); + $crate::nix::tests::compile_nix($src, vec![($dep_package, $dep_name, $dep_src)]) + .expect("compilation failed"); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }}; (($dep_package:expr, $dep_name:expr, $dep_src:expr), $src:expr, $nix:expr $(,)?) => {{ let output = - $crate::nix::tests::compile_nix($src, Some(($dep_package, $dep_name, $dep_src))); + $crate::nix::tests::compile_nix($src, Some(($dep_package, $dep_name, $dep_src))) + .expect("compilation failed"); assert_eq!(($src, output), ($src, $nix.to_string())); }}; ($src:expr $(,)?) => {{ - let output = $crate::nix::tests::compile_nix($src, vec![]); + let output = $crate::nix::tests::compile_nix($src, vec![]).expect("compilation failed"); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }}; ($src:expr, $js:expr $(,)?) => {{ - let output = $crate::nix::tests::compile_nix($src, vec![]); + let output = $crate::nix::tests::compile_nix($src, vec![]).expect("compilation failed"); assert_eq!(($src, output), ($src, $js.to_string())); }}; } +#[macro_export] +macro_rules! assert_nix_error { + ($src:expr $(,)?) => {{ + let output = $crate::nix::tests::expect_nix_error($src, vec![]); + insta::assert_snapshot!(insta::internals::AutoName, output, $src); + }}; +} + pub fn compile(src: &str, deps: Vec<(&str, &str, &str)>) -> TypedModule { let mut modules = im::HashMap::new(); let ids = UniqueIdGenerator::new(); @@ -136,7 +146,7 @@ pub fn compile(src: &str, deps: Vec<(&str, &str, &str)>) -> TypedModule { .expect("should successfully infer") } -pub fn compile_nix(src: &str, deps: Vec<(&str, &str, &str)>) -> String { +pub fn compile_nix(src: &str, deps: Vec<(&str, &str, &str)>) -> Result { let ast = compile(src, deps); let line_numbers = LineNumbers::new(src); module( @@ -144,7 +154,22 @@ pub fn compile_nix(src: &str, deps: Vec<(&str, &str, &str)>) -> String { &line_numbers, Utf8Path::new(""), &"".into(), - TargetSupport::NotEnforced, + TargetSupport::Enforced, ) - .unwrap() +} + +pub fn expect_nix_error(src: &str, deps: Vec<(&str, &str, &str)>) -> String { + let error = compile_nix(src, deps).expect_err("should not compile"); + println!("er: {:#?}", error); + let better_error = match error { + crate::Error::Nix { + error: inner_error, .. + } => crate::Error::Nix { + src: src.into(), + path: Utf8PathBuf::from("/src/nix/error.gleam"), + error: inner_error, + }, + _ => panic!("expected nix error, got {:#?}", error), + }; + better_error.pretty_string() } diff --git a/compiler-core/src/nix/tests/bit_arrays.rs b/compiler-core/src/nix/tests/bit_arrays.rs index 5dcf635a7..6f91b51ff 100644 --- a/compiler-core/src/nix/tests/bit_arrays.rs +++ b/compiler-core/src/nix/tests/bit_arrays.rs @@ -1,4 +1,4 @@ -use crate::assert_nix; +use crate::{assert_nix, assert_nix_error}; #[test] fn empty() { @@ -178,6 +178,31 @@ fn go(x) { ); } +// TODO: new error message when updating Nix bit arrays +#[test] +fn match_dynamic_size_error() { + assert_nix_error!( + r#" +fn go(x) { + let n = 16 + let assert <> = x +} +"# + ); +} + +// TODO: update Nix bit arrays with this check +// #[test] +// fn match_non_byte_aligned_size_error() { +// assert_nix_error!( +// r#" +// fn go(x) { +// let assert <> = x +// } +// "# +// ); +// } + #[test] fn discard_sized() { assert_nix!( @@ -200,6 +225,18 @@ fn go(x) { ); } +// TODO: new error message when updating Nix bit arrays +#[test] +fn match_float_16_bit_error() { + assert_nix_error!( + r#" +fn go(x) { + let assert <> = x +} +"# + ); +} + #[test] fn match_rest() { assert_nix!( @@ -260,7 +297,7 @@ fn go() { // https://github.com/gleam-lang/gleam/issues/1591 #[test] fn not_byte_aligned() { - assert_nix!( + assert_nix_error!( r#" fn thing() { 4 @@ -274,7 +311,7 @@ fn go() { #[test] fn not_byte_aligned_explicit_sized() { - assert_nix!( + assert_nix_error!( r#" fn go() { <<256:size(4)>> @@ -297,3 +334,32 @@ fn go() { "#, ); } + +#[test] +fn bit_array_literal_string_constant_is_treated_as_utf8() { + assert_nix!(r#"const a = <<"hello", " ", "world">>"#); +} + +#[test] +fn bit_array_literal_string_is_treated_as_utf8() { + assert_nix!( + r#" +pub fn main() { + <<"hello", " ", "world">> +}"# + ); +} + +// TODO: update nix bit array support to include utf8 +// #[test] +// fn bit_array_literal_string_pattern_is_treated_as_utf8() { +// assert_nix!( +// r#" +// pub fn main() { +// case <<>> { +// <<"a", "b", _:bytes>> -> 1 +// _ -> 2 +// } +// }"# +// ); +// } diff --git a/compiler-core/src/nix/tests/consts.rs b/compiler-core/src/nix/tests/consts.rs index ccbf9c50c..1b1d85063 100644 --- a/compiler-core/src/nix/tests/consts.rs +++ b/compiler-core/src/nix/tests/consts.rs @@ -33,3 +33,9 @@ pub const y = gleam.Ok "#, ); } + +// https://github.com/lpil/decode/pull/6 +#[test] +fn constructor_function_in_constant() { + assert_nix!("pub const a = Ok"); +} diff --git a/compiler-core/src/nix/tests/externals.rs b/compiler-core/src/nix/tests/externals.rs index aeb9f2123..230306e16 100644 --- a/compiler-core/src/nix/tests/externals.rs +++ b/compiler-core/src/nix/tests/externals.rs @@ -1,4 +1,4 @@ -use crate::{assert_module_error, assert_nix}; +use crate::{assert_module_error, assert_nix, assert_nix_error}; #[test] fn type_() { @@ -374,7 +374,7 @@ pub fn should_not_be_generated(x: Int) -> Int #[test] fn erlang_bit_patterns() { - assert_nix!( + assert_nix_error!( r#" pub fn should_not_be_generated(x) { case x { diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__assert.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__assert.snap index 1b1f016b1..2fa1f4d22 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__assert.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__assert.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/assignments.rs expression: "fn go(x) { let assert 1 = x }" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -10,11 +11,11 @@ let if x != 1 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 1 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__assert1.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__assert1.snap index 6d139c88d..25b29cb54 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__assert1.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__assert1.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/assignments.rs expression: "fn go(x) { let assert #(1, 2) = x }" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -10,11 +11,11 @@ let if (builtins.elemAt x 0) != 1 || (builtins.elemAt x 1) != 2 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 1 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__let_assert_string_prefix.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__let_assert_string_prefix.snap index f515981e3..3e67fdc46 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__let_assert_string_prefix.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__let_assert_string_prefix.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/assignments.rs expression: "\npub fn main(x) {\n let assert \"Game \" <> id = x\n id\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) strHasPrefix makeError; @@ -12,11 +13,11 @@ let if !(strHasPrefix "Game " x) then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "main" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; id = builtins.seq _assert' (builtins.substring 5 (-1) x); diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__nested_binding.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__nested_binding.snap index 7e4ca261b..e0c361678 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__nested_binding.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__nested_binding.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/assignments.rs expression: "\nfn go(x) {\n let assert #(a, #(b, c, 2) as t, _, 1) = x\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -13,11 +14,11 @@ let then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__returning_literal_subject.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__returning_literal_subject.snap index 8edca8399..f085eba1e 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__returning_literal_subject.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__returning_literal_subject.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/assignments.rs expression: "fn go(x) { let assert 1 = x + 1 }" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -13,11 +14,11 @@ let if _pat' != 1 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 1 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = _pat'; }) else _pat'; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__tuple_matching.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__tuple_matching.snap index 7b04f849b..7d325accb 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__tuple_matching.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__tuple_matching.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/assignments.rs expression: "\nfn go(x) {\n let assert #(1, 2) = x\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -10,11 +11,11 @@ let if (builtins.elemAt x 0) != 1 || (builtins.elemAt x 1) != 2 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__variable_renaming.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__variable_renaming.snap index 7526402ba..0494bece5 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__variable_renaming.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__assignments__variable_renaming.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/assignments.rs expression: "\n\nfn go(x, wibble) {\n let a = 1\n wibble(a)\n let a = 2\n wibble(a)\n let assert #(a, 3) = x\n let b = a\n wibble(b)\n let c = {\n let a = a\n #(a, b)\n }\n wibble(a)\n // make sure arguments are counted in initial state\n let x = c\n x\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError seqAll; @@ -16,11 +17,11 @@ let if (builtins.elemAt x 1) != 3 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 8 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; a'2 = builtins.seq _assert' (builtins.elemAt x 0); diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__basic__basic_let_pat_test.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__basic__basic_let_pat_test.snap index 9fd2eab41..cd976172e 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__basic__basic_let_pat_test.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__basic__basic_let_pat_test.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/basic.rs expression: "\npub type Test {\n A\n B(Int)\n C(a: Int, b: Float)\n}\n\npub type Simple {\n Simple\n}\npub type Simple2 {\n Simple2(Int)\n}\npub type Simple3 {\n Simple3(inherit: Bool, x: Float)\n}\n\npub fn pat_test() {\n let Nil = Nil\n let x = Simple\n let Simple = x\n let Simple = Simple\n let _ = Simple2(5)\n let _ignored = Simple2(5)\n let Simple2(a) = Simple2(5)\n let Simple3(a, b) = Simple3(True, 5.0)\n\n #(a, b)\n}\n\npub fn pat_assert_test() {\n let assert True = True\n let assert False = True\n let assert A = A\n let assert B(x) = B(5)\n let assert C(a: a, b: b) = C(a: 5, b: 5.5e5)\n let assert C(a: a, b: b) = C(a: 5, b: 5.5e5)\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError seqAll; @@ -47,11 +48,11 @@ let if !_pat' then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 32 "pat_assert_test" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = _pat'; }) else null; _' = builtins.seq _assert' _pat'; @@ -60,11 +61,11 @@ let if _pat''1 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 33 "pat_assert_test" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = _pat''1; }) else null; _'1 = builtins.seq _assert''1 _pat''1; @@ -73,11 +74,11 @@ let if _pat''2.__gleamTag != "A" then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 34 "pat_assert_test" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = _pat''2; }) else null; _'2 = builtins.seq _assert''2 _pat''2; @@ -86,11 +87,11 @@ let if _pat''3.__gleamTag != "B" then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 35 "pat_assert_test" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = _pat''3; }) else null; x = builtins.seq _assert''3 _pat''3._0; @@ -99,11 +100,11 @@ let if _pat''4.__gleamTag != "C" then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 36 "pat_assert_test" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = _pat''4; }) else null; a = builtins.seq _assert''4 _pat''4.a; @@ -117,11 +118,11 @@ let if _pat''5.__gleamTag != "C" then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 37 "pat_assert_test" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = _pat''5; }) else _pat''5); in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__basic__basic_test.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__basic__basic_test.snap index 840c520d5..815fa74c4 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__basic__basic_test.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__basic__basic_test.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/basic.rs expression: "\npub type Amogus {\n AmogusA\n AmogusB(a: Int, b: Int)\n AmogusC(Int, Float)\n}\n\npub const sumongus: Int = 5\n\npub fn sus(x: Int) -> Int {\n 5 + 5\n}\n\nfn go(x, wibble, boolthing, bmong) {\n let a = 1\n wibble\n let a = 2\n let z = [fn(y: Int) { y }, wibble(a, a, 50), fn(x: Int) { x }]\n let d = {\n \"aaa\"\n }\n let dd = {\n let amogus = 5.5e5\n }\n let intdiv = 5 / 5\n let floatdiv = 5.0 /. 5.0\n let remm = 5 % 5\n let g = 0.5\n let b = a\n wibble(a, a, 50)\n let c = {\n let a = a\n [a]\n }\n wibble\n let www = a == 5\n let wwww = {a + a} == {10 - 5 * 5}\n let first_list = [1 < 4, 3 >= 5]\n let list_thing = [www, ..first_list]\n let pipes =\n a\n |> wibble(_, a, 50)\n |> fn(x) { x }\n let pipes2 = a |> fn(i: Int) { i }\n panic as \"amongus\"\n todo as \"amongus\"\n panic\n todo\n // let mongus: Amogus = bmong\n // let mongus = bmong.a\n // let mongus = Amogus(..bmong, a: 6)\n let y = -500 + 10 - {-a} - {-5}\n let yy = [ -a, -5, -y ]\n let f = -5.5 -. 5.2e-5\n let f = 5.5 -. 5.2e5\n // TODO: fix string escaping\n let ss = \"a\" <> \"b\" <> \"c d\"\n let ff = [ -5.2e-5, -5.5 ]\n let z = !boolthing\n let tupdatup = #(1, 2, \"a\", -5.5, #(1, 2, 3))\n let tata = tupdatup.1 + tupdatup.0 + 20\n let mabool = True\n let mnotbool = False\n let amagus_a = AmogusA\n let amagus_b = AmogusB(10, b: 15)\n let amagus_c = AmogusC(10, 5.5)\n let simplefunc = fn() { 5 }\n let gg = simplefunc() + 10\n let less_simple_func = fn(x) { fn() { x } }\n let gg = less_simple_func(5)() + 10\n let mnull = Nil\n let sus = \"hey! I'm still sus :(\"\n // make sure arguments are counted in initial state\n let x = tata\n x\n}\n\nfn mongus(a, b, c) {\n let x = fn() { 5 + 5 }\n let y = x()\n #(1, 2, 3, fn(x: Int) { x + 1 }, { 5 6 10 {10 + 5} })\n}\n" +snapshot_kind: text --- let inherit @@ -54,7 +55,13 @@ let _'4 = builtins.throw (makeError "todo" "my/mod" 46 "go" "amongus" { }); _'5 = builtins.throw - (makeError "panic" "my/mod" 47 "go" "panic expression evaluated" { }); + (makeError + "panic" + "my/mod" + 47 + "go" + "`panic` expression evaluated." + { }); _'6 = builtins.throw (makeError @@ -62,7 +69,7 @@ let "my/mod" 48 "go" - "This has not yet been implemented" + "`todo` expression evaluated. This code has not yet been implemented." { }); y = (((-500) + 10) - (-a'1)) - (-5); yy = toList [ (-a'1) (-5) (-y) ]; diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap new file mode 100644 index 000000000..fd78d17da --- /dev/null +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__bit_array_literal_string_constant_is_treated_as_utf8.snap @@ -0,0 +1,11 @@ +--- +source: compiler-core/src/nix/tests/bit_arrays.rs +expression: "const a = <<\"hello\", \" \", \"world\">>" +snapshot_kind: text +--- +let + inherit (builtins.import ./../gleam.nix) toBitArray stringBits; + + a = toBitArray [ (stringBits "hello") (stringBits " ") (stringBits "world") ]; +in +{ } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap new file mode 100644 index 000000000..7e9ca63ac --- /dev/null +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__bit_array_literal_string_is_treated_as_utf8.snap @@ -0,0 +1,13 @@ +--- +source: compiler-core/src/nix/tests/bit_arrays.rs +expression: "\npub fn main() {\n <<\"hello\", \" \", \"world\">>\n}" +snapshot_kind: text +--- +let + inherit (builtins.import ./../gleam.nix) toBitArray stringBits; + + main = + { }: + toBitArray [ (stringBits "hello") (stringBits " ") (stringBits "world") ]; +in +{ inherit main; } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__discard_sized.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__discard_sized.snap index 40d01d96d..53372fa31 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__discard_sized.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__discard_sized.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bit_arrays.rs expression: "\nfn go(x) {\n let assert <<_:16, _:8>> = x\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError byteSize intFromBitSlice; @@ -10,11 +11,11 @@ let if byteSize x != 3 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__empty_match.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__empty_match.snap index d8e1c77b5..32486b845 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__empty_match.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__empty_match.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bit_arrays.rs expression: "\nfn go(x) {\n let assert <<>> = x\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError byteSize; @@ -10,11 +11,11 @@ let if byteSize x != 0 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_binary_size.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_binary_size.snap index df300a5cd..4d6d7b5be 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_binary_size.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_binary_size.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bit_arrays.rs expression: "\nfn go(x) {\n let assert <<_, a:2-bytes>> = x\n let assert <<_, b:bytes-size(2)>> = x\n #(a, b)\n}\n" +snapshot_kind: text --- let inherit @@ -19,11 +20,11 @@ let if byteSize x != 3 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; a = builtins.seq _assert' (binaryFromBitSlice x 1 3); @@ -31,11 +32,11 @@ let if byteSize x != 3 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 4 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; b = builtins.seq _assert''1 (binaryFromBitSlice x 1 3); diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_bytes.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_bytes.snap index c3fd7c88d..e9ba4a2f3 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_bytes.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_bytes.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bit_arrays.rs expression: "\nfn go(x) {\n let assert <<1, y>> = x\n y\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError byteSize byteAt; @@ -12,11 +13,11 @@ let if (byteAt x 0) != 1 || byteSize x != 2 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; y = builtins.seq _assert' (byteAt x 1); diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_dynamic_size_error.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_dynamic_size_error.snap new file mode 100644 index 000000000..04d11cd0a --- /dev/null +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_dynamic_size_error.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/nix/tests/bit_arrays.rs +expression: "\nfn go(x) {\n let n = 16\n let assert <> = x\n}\n" +snapshot_kind: text +--- +error: Unsupported feature for compilation target + ┌─ /src/nix/error.gleam:4:16 + │ +4 │ let assert <> = x + │ ^^^^^^^^^ + +This bit array size option in patterns is not supported for Nix compilation. diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_float_16_bit_error.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_float_16_bit_error.snap new file mode 100644 index 000000000..ce103101b --- /dev/null +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_float_16_bit_error.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/nix/tests/bit_arrays.rs +expression: "\nfn go(x) {\n let assert <> = x\n}\n" +snapshot_kind: text +--- +error: Unsupported feature for compilation target + ┌─ /src/nix/error.gleam:3:16 + │ +3 │ let assert <> = x + │ ^^^^^^^^^^^^^^^^ + +This bit array segment option in patterns is not supported for Nix compilation. diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_rest.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_rest.snap index 8b096ea89..bf48a1d59 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_rest.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_rest.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bit_arrays.rs expression: "\nfn go(x) {\n let assert <<_, b:bytes>> = <<1,2,3>>\n b\n}\n" +snapshot_kind: text --- let inherit @@ -20,11 +21,11 @@ let if byteSize _pat' < 1 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = _pat'; }) else null; b = builtins.seq _assert' (bitSliceAfter _pat' 1); diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_sized.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_sized.snap index c7f9ddb1e..68415a6f6 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_sized.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_sized.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bit_arrays.rs expression: "\nfn go(x) {\n let assert <> = x\n #(a, b)\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError byteSize intFromBitSlice; @@ -12,11 +13,11 @@ let if byteSize x != 3 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; a = builtins.seq _assert' (intFromBitSlice x 0 2); diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_sized_value.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_sized_value.snap index 94ee34586..6635f396d 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_sized_value.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__match_sized_value.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bit_arrays.rs expression: "\nfn go(x) {\n let assert <<258:16>> = x\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError byteSize intFromBitSlice; @@ -10,11 +11,11 @@ let if (intFromBitSlice x 0 2) != 258 || byteSize x != 2 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__not_byte_aligned.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__not_byte_aligned.snap index cb6a065ec..3b2adce42 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__not_byte_aligned.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__not_byte_aligned.snap @@ -1,5 +1,12 @@ --- source: compiler-core/src/nix/tests/bit_arrays.rs expression: "\nfn thing() {\n 4\n}\nfn go() {\n <<256:4>>\n}\n" +snapshot_kind: text --- -let inherit (builtins.import ./../gleam.nix) toBitArray; thing = { }: 4; in { } +error: Unsupported feature for compilation target + ┌─ /src/nix/error.gleam:6:5 + │ +6 │ <<256:4>> + │ ^^^^^ + +Non byte aligned array is not supported for Nix compilation. diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__not_byte_aligned_explicit_sized.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__not_byte_aligned_explicit_sized.snap index e32a47bdc..fd3704c3a 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__not_byte_aligned_explicit_sized.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bit_arrays__not_byte_aligned_explicit_sized.snap @@ -1,5 +1,12 @@ --- source: compiler-core/src/nix/tests/bit_arrays.rs expression: "\nfn go() {\n <<256:size(4)>>\n}\n" +snapshot_kind: text --- -let inherit (builtins.import ./../gleam.nix) toBitArray; in { } +error: Unsupported feature for compilation target + ┌─ /src/nix/error.gleam:3:5 + │ +3 │ <<256:size(4)>> + │ ^^^^^^^^^^^ + +Non byte aligned array is not supported for Nix compilation. diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__assigning.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__assigning.snap index 9a4068f6d..2f7fb9ba0 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__assigning.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__assigning.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bools.rs expression: "\nfn go(x, y) {\n let assert True = x\n let assert False = x\n let assert Nil = y\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError seqAll; @@ -12,11 +13,11 @@ let if !x then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; _' = builtins.seq _assert' x; @@ -24,11 +25,11 @@ let if x then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 4 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; _'1 = builtins.seq _assert''1 x; @@ -38,11 +39,11 @@ let (if y != null then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 5 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = y; }) else y); in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_panic_left.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_panic_left.snap index 6b1fc7ea8..d8950571e 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_panic_left.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_panic_left.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bools.rs expression: "pub fn negate(x) {\n panic && x\n}" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -8,6 +9,6 @@ let negate = x: (builtins.throw - (makeError "panic" "my/mod" 2 "negate" "panic expression evaluated" { })) && x; + (makeError "panic" "my/mod" 2 "negate" "`panic` expression evaluated." { })) && x; in { inherit negate; } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_panic_right.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_panic_right.snap index 58e673c45..e09520bc7 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_panic_right.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_panic_right.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bools.rs expression: "pub fn negate(x) {\n x && panic\n}" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -8,6 +9,6 @@ let negate = x: x && (builtins.throw - (makeError "panic" "my/mod" 2 "negate" "panic expression evaluated" { })); + (makeError "panic" "my/mod" 2 "negate" "`panic` expression evaluated." { })); in { inherit negate; } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_todo_left.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_todo_left.snap index 230b4a77a..533f17a14 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_todo_left.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_todo_left.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bools.rs expression: "pub fn negate(x) {\n todo && x\n}" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -13,7 +14,7 @@ let "my/mod" 2 "negate" - "This has not yet been implemented" + "`todo` expression evaluated. This code has not yet been implemented." { })) && x; in { inherit negate; } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_todo_right.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_todo_right.snap index 116ee1b59..1b6f2a90c 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_todo_right.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__binop_todo_right.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bools.rs expression: "pub fn negate(x) {\n x && todo\n}" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -13,7 +14,7 @@ let "my/mod" 2 "negate" - "This has not yet been implemented" + "`todo` expression evaluated. This code has not yet been implemented." { })); in { inherit negate; } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__negate_panic.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__negate_panic.snap index 90b9c446b..0eb6e2ee6 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__negate_panic.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__negate_panic.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bools.rs expression: "pub fn negate(x) {\n !panic\n}" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -8,6 +9,6 @@ let negate = x: !(builtins.throw - (makeError "panic" "my/mod" 2 "negate" "panic expression evaluated" { })); + (makeError "panic" "my/mod" 2 "negate" "`panic` expression evaluated." { })); in { inherit negate; } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__negate_todo.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__negate_todo.snap index 8cae4f6b7..464a43aac 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__negate_todo.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__negate_todo.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bools.rs expression: "pub fn negate(x) {\n !todo\n}" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -13,7 +14,7 @@ let "my/mod" 2 "negate" - "This has not yet been implemented" + "`todo` expression evaluated. This code has not yet been implemented." { })); in { inherit negate; } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__shadowed_bools_and_nil.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__shadowed_bools_and_nil.snap index 6ad9e16d3..acd887cfd 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__shadowed_bools_and_nil.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__bools__shadowed_bools_and_nil.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/bools.rs expression: "\npub type True { True False Nil }\nfn go(x, y) {\n let assert True = x\n let assert False = x\n let assert Nil = y\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError seqAll; @@ -18,11 +19,11 @@ let if x.__gleamTag != "True" then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 4 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; _' = builtins.seq _assert' x; @@ -30,11 +31,11 @@ let if x.__gleamTag != "False" then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 5 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; _'1 = builtins.seq _assert''1 x; @@ -44,11 +45,11 @@ let (if y.__gleamTag != "Nil" then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 6 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = y; }) else y); in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__case__following_todo.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__case__following_todo.snap index d68655e92..83c6a1373 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__case__following_todo.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__case__following_todo.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/case.rs expression: "\nfn go(x) {\n case x {\n True -> todo\n _ -> 1\n }\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -14,7 +15,7 @@ let "my/mod" 4 "go" - "This has not yet been implemented" + "`todo` expression evaluated. This code has not yet been implemented." { }) else 1; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__consts__constructor_function_in_constant.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__consts__constructor_function_in_constant.snap new file mode 100644 index 000000000..70c9df950 --- /dev/null +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__consts__constructor_function_in_constant.snap @@ -0,0 +1,6 @@ +--- +source: compiler-core/src/nix/tests/consts.rs +expression: pub const a = Ok +snapshot_kind: text +--- +let inherit (builtins.import ./../gleam.nix) Ok; a = Ok; in { inherit a; } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__consts__imported_ok.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__consts__imported_ok.snap index cb68a78e0..e13336194 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__consts__imported_ok.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__consts__imported_ok.snap @@ -1,12 +1,14 @@ --- source: compiler-core/src/nix/tests/consts.rs expression: "import gleam\npub type X {\n Ok\n}\npub const y = gleam.Ok\n" +snapshot_kind: text --- let gleam' = builtins.import ./../gleam.nix; + inherit (builtins.import ./../gleam.nix) Ok; Ok = { __gleamTag = "Ok"; }; - y = gleam'.Ok; + y = Ok; in { inherit Ok y; } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__custom_types__destructure_custom_type_with_named_fields.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__custom_types__destructure_custom_type_with_named_fields.snap index d1b6034a5..55fbcdaa6 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__custom_types__destructure_custom_type_with_named_fields.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__custom_types__destructure_custom_type_with_named_fields.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/custom_types.rs expression: "\ntype Cat {\n Cat(name: String, cuteness: Int)\n}\n\nfn go(cat) {\n let Cat(x, y) = cat\n let Cat(name: x, ..) = cat\n let assert Cat(cuteness: 4, name: x) = cat\n x\n}\n\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -17,11 +18,11 @@ let if cat.__gleamTag != "Cat" || cat.cuteness != 4 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 9 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = cat; }) else null; x'2 = builtins.seq _assert' cat.name; diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__attribute_erlang.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__attribute_erlang.snap index 68f26fefc..7906c6076 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__attribute_erlang.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__attribute_erlang.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/externals.rs expression: "\n@external(erlang, \"one\", \"one_erl\")\npub fn one(x: Int) -> Int {\n todo\n}\n\npub fn main() {\n one(1)\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -8,7 +9,13 @@ let one = x: builtins.throw - (makeError "todo" "my/mod" 4 "one" "This has not yet been implemented" { }); + (makeError + "todo" + "my/mod" + 4 + "one" + "`todo` expression evaluated. This code has not yet been implemented." + { }); main = { }: one 1; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__attribute_javascript.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__attribute_javascript.snap index 4aca3a756..032982c7d 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__attribute_javascript.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__attribute_javascript.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/externals.rs expression: "\n@external(javascript, \"./one.mjs\", \"oneJs\")\npub fn one(x: Int) -> Int {\n todo\n}\n\npub fn main() {\n one(1)\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -8,7 +9,13 @@ let one = x: builtins.throw - (makeError "todo" "my/mod" 4 "one" "This has not yet been implemented" { }); + (makeError + "todo" + "my/mod" + 4 + "one" + "`todo` expression evaluated. This code has not yet been implemented." + { }); main = { }: one 1; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__erlang_bit_patterns.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__erlang_bit_patterns.snap index 554dca378..34ec21819 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__erlang_bit_patterns.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__erlang_bit_patterns.snap @@ -1,5 +1,12 @@ --- source: compiler-core/src/nix/tests/externals.rs expression: "\npub fn should_not_be_generated(x) {\n case x {\n <<_, rest:bits>> -> rest\n _ -> x\n }\n}\n" +snapshot_kind: text --- -let inherit (builtins.import ./../gleam.nix) byteAt; in { } +error: Unsupported feature for compilation target + ┌─ /src/nix/error.gleam:4:10 + │ +4 │ <<_, rest:bits>> -> rest + │ ^^^^^^^^^ + +This bit array segment option in patterns is not supported for Nix compilation. diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__private_attribute_erlang.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__private_attribute_erlang.snap index 011468994..b02bb45f9 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__private_attribute_erlang.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__private_attribute_erlang.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/externals.rs expression: "\n@external(erlang, \"one\", \"one_erl\")\nfn one(x: Int) -> Int {\n todo\n}\n\npub fn main() {\n one(1)\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -8,7 +9,13 @@ let one = x: builtins.throw - (makeError "todo" "my/mod" 4 "one" "This has not yet been implemented" { }); + (makeError + "todo" + "my/mod" + 4 + "one" + "`todo` expression evaluated. This code has not yet been implemented." + { }); main = { }: one 1; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__private_attribute_javascript.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__private_attribute_javascript.snap index 25338ec1e..aef6c3256 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__private_attribute_javascript.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__externals__private_attribute_javascript.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/externals.rs expression: "\n@external(javascript, \"./one.mjs\", \"oneJs\")\nfn one(x: Int) -> Int {\n todo\n}\n\npub fn main() {\n one(1)\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -8,7 +9,13 @@ let one = x: builtins.throw - (makeError "todo" "my/mod" 4 "one" "This has not yet been implemented" { }); + (makeError + "todo" + "my/mod" + 4 + "one" + "`todo` expression evaluated. This code has not yet been implemented." + { }); main = { }: one 1; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__lists__list_destructuring.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__lists__list_destructuring.snap index 377ba88a0..971a39daa 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__lists__list_destructuring.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__lists__list_destructuring.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/lists.rs expression: "\nfn go(x, y) {\n let assert [] = x\n let assert [a] = x\n let assert [1, 2] = x\n let assert [_, #(3, b)] = y\n let assert [head, ..tail] = y\n}\n" +snapshot_kind: text --- let inherit @@ -18,11 +19,11 @@ let if !(listHasLength x 0) then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; _' = builtins.seq _assert' x; @@ -30,11 +31,11 @@ let if !(listHasLength x 1) then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 4 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; a = builtins.seq _assert''1 x.head; @@ -42,11 +43,11 @@ let if !(listHasLength x 2) || x.head != 1 || x.tail.head != 2 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 5 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else null; _'1 = builtins.seq _assert''2 x; @@ -54,11 +55,11 @@ let if !(listHasLength y 2) || (builtins.elemAt y.tail.head 0) != 3 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 6 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = y; }) else null; b = builtins.seq _assert''3 (builtins.elemAt y.tail.head 1); @@ -68,11 +69,11 @@ let (if !(listHasAtLeastLength y 1) then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 7 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = y; }) else y); in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__int_patterns.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__int_patterns.snap index 2328f19ff..e3cd5c331 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__int_patterns.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__int_patterns.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/numbers.rs expression: "\nfn go(x) {\n let assert 4 = x\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -10,11 +11,11 @@ let if x != 4 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__preceeding_zeros_float_pattern.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__preceeding_zeros_float_pattern.snap index 31868bdc8..5317da123 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__preceeding_zeros_float_pattern.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__preceeding_zeros_float_pattern.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/numbers.rs expression: "\nfn main(x) {\n let assert 09_179.1 = x\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -10,11 +11,11 @@ let if x != 9179.1 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "main" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__preceeding_zeros_int_pattern.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__preceeding_zeros_int_pattern.snap index fec3e8bdc..5f793c322 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__preceeding_zeros_int_pattern.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__numbers__preceeding_zeros_int_pattern.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/numbers.rs expression: "\nfn main(x) {\n let assert 09_179 = x\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -10,11 +11,11 @@ let if x != 9179 then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "main" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__as_expression.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__as_expression.snap index 6860ba05c..1fdda6297 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__as_expression.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__as_expression.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/panic.rs expression: "\nfn go(f) {\n let boop = panic\n f(panic)\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -10,10 +11,10 @@ let let boop = builtins.throw - (makeError "panic" "my/mod" 3 "go" "panic expression evaluated" { }); + (makeError "panic" "my/mod" 3 "go" "`panic` expression evaluated." { }); in f (builtins.throw - (makeError "panic" "my/mod" 4 "go" "panic expression evaluated" { })); + (makeError "panic" "my/mod" 4 "go" "`panic` expression evaluated." { })); in { } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__bare.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__bare.snap index 5db806708..0e9a06760 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__bare.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__bare.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/panic.rs expression: "\nfn go() {\n panic\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -8,6 +9,6 @@ let go = { }: builtins.throw - (makeError "panic" "my/mod" 3 "go" "panic expression evaluated" { }); + (makeError "panic" "my/mod" 3 "go" "`panic` expression evaluated." { }); in { } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__case.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__case.snap index e8ea83a99..c6e403fd8 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__case.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__case.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/panic.rs expression: "\nfn go(x) {\n case x {\n _ -> panic\n }\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -8,6 +9,6 @@ let go = x: builtins.throw - (makeError "panic" "my/mod" 4 "go" "panic expression evaluated" { }); + (makeError "panic" "my/mod" 4 "go" "`panic` expression evaluated." { }); in { } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__pipe.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__pipe.snap index b1a988ba3..e0016801c 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__pipe.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__pipe.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/panic.rs expression: "\nfn go(f) {\n f |> panic\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -11,7 +12,7 @@ let _pipe = f; in (builtins.throw - (makeError "panic" "my/mod" 3 "go" "panic expression evaluated" { })) + (makeError "panic" "my/mod" 3 "go" "`panic` expression evaluated." { })) _pipe; in { } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__sequence.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__sequence.snap index ed449a84d..2438f7afd 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__sequence.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__panic__sequence.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/panic.rs expression: "\nfn go(at_the_disco) {\n panic\n at_the_disco\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -10,7 +11,7 @@ let let _' = builtins.throw - (makeError "panic" "my/mod" 3 "go" "panic expression evaluated" { }); + (makeError "panic" "my/mod" 3 "go" "`panic` expression evaluated." { }); in builtins.seq _' at_the_disco; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__strings__string_patterns.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__strings__string_patterns.snap index b7c7cbfde..15fce52f9 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__strings__string_patterns.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__strings__string_patterns.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/strings.rs expression: "\nfn go(x) {\n let assert \"Hello\" = x\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -10,11 +11,11 @@ let if x != "Hello" then builtins.throw (makeError - "assignment_no_match" + "let_assert" "my/mod" 3 "go" - "Assignment pattern did not match" + "Pattern match failed, no pattern matched the value." { value = x; }) else x; in diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__todo__without_message.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__todo__without_message.snap index bb3bcc979..1df73ba9d 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__todo__without_message.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__todo__without_message.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/todo.rs expression: "\nfn go() {\n todo\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -8,6 +9,12 @@ let go = { }: builtins.throw - (makeError "todo" "my/mod" 3 "go" "This has not yet been implemented" { }); + (makeError + "todo" + "my/mod" + 3 + "go" + "`todo` expression evaluated. This code has not yet been implemented." + { }); in { } diff --git a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__use___no_callback_body.snap b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__use___no_callback_body.snap index 002e9b4c3..45d3bc258 100644 --- a/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__use___no_callback_body.snap +++ b/compiler-core/src/nix/tests/snapshots/glistix_core__nix__tests__use___no_callback_body.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/nix/tests/use_.rs expression: "\npub fn main() {\n let thingy = fn(f) { f() }\n use <- thingy()\n}\n" +snapshot_kind: text --- let inherit (builtins.import ./../gleam.nix) makeError; @@ -18,7 +19,7 @@ let "my/mod" 4 "main" - "This has not yet been implemented" + "`todo` expression evaluated. This code has not yet been implemented." { })); in { inherit main; } diff --git a/compiler-core/src/package_interface.rs b/compiler-core/src/package_interface.rs index b9377e132..aabf91357 100644 --- a/compiler-core/src/package_interface.rs +++ b/compiler-core/src/package_interface.rs @@ -373,7 +373,11 @@ impl PackageInterface { PackageInterface { name: package.config.name.clone(), version: package.config.version.to_string().into(), - gleam_version_constraint: package.config.gleam_version.clone(), + gleam_version_constraint: package + .config + .gleam_version + .clone() + .map(|version| EcoString::from(version.to_string())), modules: package .modules .iter() diff --git a/compiler-core/src/package_interface/tests.rs b/compiler-core/src/package_interface/tests.rs index 07376ab53..bb731e34c 100644 --- a/compiler-core/src/package_interface/tests.rs +++ b/compiler-core/src/package_interface/tests.rs @@ -153,7 +153,11 @@ fn package_from_module(module: Module) -> Package { ], build: Some("build".into()), }, - gleam_version: Some("1.0.0".into()), + gleam_version: Some( + hexpm::version::Range::new("1.0.0".into()) + .to_pubgrub() + .unwrap(), + ), licences: vec![], description: "description".into(), documentation: Docs { pages: vec![] }, diff --git a/compiler-core/src/parse.rs b/compiler-core/src/parse.rs index fa68ded87..fe2927515 100644 --- a/compiler-core/src/parse.rs +++ b/compiler-core/src/parse.rs @@ -66,6 +66,7 @@ use crate::ast::{ CAPTURE_VARIABLE, }; use crate::build::Target; +use crate::error::wrap; use crate::parse::extra::ModuleExtra; use crate::type_::expression::Implementations; use crate::type_::Deprecation; @@ -116,9 +117,9 @@ enum InternalAttribute { struct Attributes { target: Option, deprecated: Deprecation, - external_erlang: Option<(EcoString, EcoString)>, - external_javascript: Option<(EcoString, EcoString)>, - external_nix: Option<(EcoString, EcoString)>, + external_erlang: Option<(EcoString, EcoString, SrcSpan)>, + external_javascript: Option<(EcoString, EcoString, SrcSpan)>, + external_nix: Option<(EcoString, EcoString, SrcSpan)>, internal: InternalAttribute, } @@ -137,7 +138,7 @@ impl Attributes { } } - fn set_external_for(&mut self, target: Target, ext: Option<(EcoString, EcoString)>) { + fn set_external_for(&mut self, target: Target, ext: Option<(EcoString, EcoString, SrcSpan)>) { match target { Target::Erlang => self.external_erlang = ext, Target::JavaScript => self.external_javascript = ext, @@ -146,11 +147,12 @@ impl Attributes { } } -type SpannedString = (SrcSpan, EcoString); - // // Public Interface // + +pub type SpannedString = (SrcSpan, EcoString); + pub fn parse_module( path: Utf8PathBuf, src: &str, @@ -390,6 +392,13 @@ where // unit op unit pipe unit(call) // unit op unit pipe unit(call) pipe unit(call) fn parse_expression(&mut self) -> Result, ParseError> { + self.parse_expression_inner(false) + } + + fn parse_expression_inner( + &mut self, + is_let_binding: bool, + ) -> Result, ParseError> { // uses the simple operator parser algorithm let mut opstack = vec![]; let mut estack = vec![]; @@ -397,7 +406,10 @@ where let mut last_op_end = 0; loop { match self.parse_expression_unit()? { - Some(unit) => estack.push(unit), + Some(unit) => { + self.post_process_expression_unit(&unit, is_let_binding)?; + estack.push(unit) + } _ if estack.is_empty() => return Ok(None), _ => { return parse_error( @@ -440,6 +452,23 @@ where )) } + fn post_process_expression_unit( + &mut self, + unit: &UntypedExpr, + is_let_binding: bool, + ) -> Result<(), ParseError> { + // Produce better error message for `[x] = [1]` outside + // of `let` statement. + if !is_let_binding { + if let UntypedExpr::List { .. } = unit { + if let Some((start, Token::Equal, end)) = self.tok0 { + return parse_error(ParseErrorType::NoLetBinding, SrcSpan { start, end }); + } + } + } + Ok(()) + } + fn parse_expression_unit_collapsing_single_value_blocks( &mut self, ) -> Result, ParseError> { @@ -691,6 +720,12 @@ where } } + // Helpful error if trying to write an if expression instead of a + // case. + Some((start, Token::If, end)) => { + return parse_error(ParseErrorType::IfExpression, SrcSpan { start, end }); + } + // helpful error on possibly trying to group with "" Some((start, Token::LeftParen, _)) => { return parse_error(ParseErrorType::ExprLparStart, SrcSpan { start, end: start }); @@ -736,15 +771,6 @@ where } } - // if it reaches this code block, there must be no "let" or "assert" at the beginning of the expression - Some((start, Token::Equal, end)) => { - return parse_error(ParseErrorType::NoLetBinding, SrcSpan { start, end }) - } - - Some((start, Token::Colon, end)) => { - return parse_error(ParseErrorType::NoLetBinding, SrcSpan { start, end }) - } - t0 => { self.tok0 = t0; return Ok(None); @@ -939,11 +965,18 @@ where end: pattern.location().end, }, })?; - let value = self.parse_expression()?.ok_or(ParseError { - error: ParseErrorType::ExpectedValue, - location: SrcSpan { - start: eq_s, - end: eq_e, + let value = self.parse_expression_inner(true)?.ok_or(match self.tok0 { + Some((start, Token::DiscardName { .. }, end)) => ParseError { + error: ParseErrorType::IncorrectName, + location: SrcSpan { start, end }, + }, + + _ => ParseError { + error: ParseErrorType::ExpectedValue, + location: SrcSpan { + start: eq_s, + end: eq_e, + }, }, })?; Ok(Statement::Assignment(Assignment { @@ -999,12 +1032,23 @@ where token => { self.tok0 = token; + self.parse_statement_errors()?; let expression = self.parse_expression()?.map(Statement::Expression); Ok(expression) } } } + fn parse_statement_errors(&mut self) -> Result<(), ParseError> { + // Better error: name definitions must start with `let` + if let Some((_, Token::Name { .. }, _)) = self.tok0.as_ref() { + if let Some((start, Token::Equal | Token::Colon, end)) = self.tok1 { + return parse_error(ParseErrorType::NoLetBinding, SrcSpan { start, end }); + } + } + Ok(()) + } + fn parse_block(&mut self, start: u32) -> Result { let body = self.parse_statement_seq()?; let (_, end) = self.expect_one(&Token::RightBrace)?; @@ -1364,13 +1408,18 @@ where then, })) } else { - parse_error( - ParseErrorType::ExpectedExpr, - SrcSpan { - start: arr_s, - end: arr_e, - }, - ) + match self.tok0 { + Some((start, Token::DiscardName { .. }, end)) => { + parse_error(ParseErrorType::IncorrectName, SrcSpan { start, end }) + } + _ => parse_error( + ParseErrorType::ExpectedExpr, + SrcSpan { + start: arr_s, + end: arr_e, + }, + ), + } } } else { Ok(None) @@ -1588,7 +1637,7 @@ where Ok(Pattern::Constructor { location: SrcSpan { start, end }, arguments: args, - module: module.map(|(_, n, _)| n), + module: module.map(|(start, n, end)| (n, SrcSpan { start, end })), name, spread, constructor: Inferred::Unknown, @@ -1604,17 +1653,23 @@ where upname_end: u32, ) -> Result<(Vec>, Option, u32), ParseError> { if self.maybe_one(&Token::LeftParen).is_some() { - let args = Parser::series_of( - self, + let (args, args_end_with_comma) = self.series_of_has_trailing_separator( &Parser::parse_constructor_pattern_arg, Some(&Token::Comma), )?; + let spread = self .maybe_one(&Token::DotDot) .map(|(start, end)| SrcSpan { start, end }); - if spread.is_some() { + if let Some(spread_location) = spread { let _ = self.maybe_one(&Token::Comma); + if !args.is_empty() && !args_end_with_comma { + self.warnings + .push(DeprecatedSyntaxWarning::DeprecatedRecordSpreadPattern { + location: spread_location, + }) + } } let (_, end) = self.expect_one(&Token::RightParen)?; Ok((args, spread, end)) @@ -1741,7 +1796,9 @@ where n, )); } - let _ = self.expect_one(&Token::LeftParen)?; + let _ = self + .expect_one(&Token::LeftParen) + .map_err(|e| self.add_anon_function_hint(e))?; let args = Parser::series_of( self, &|parser| Parser::parse_fn_param(parser, is_anon), @@ -1812,6 +1869,18 @@ where }))) } + fn add_anon_function_hint(&self, mut err: ParseError) -> ParseError { + if let ParseErrorType::UnexpectedToken { + ref mut hint, + token: Token::Name { .. }, + .. + } = err.error + { + *hint = Some("Only module-level functions can be named.".into()); + } + err + } + fn publicity( &self, public: bool, @@ -1820,7 +1889,9 @@ where match (internal, public) { (InternalAttribute::Missing, true) => Ok(Publicity::Public), (InternalAttribute::Missing, false) => Ok(Publicity::Private), - (InternalAttribute::Present(_), true) => Ok(Publicity::Internal), + (InternalAttribute::Present(location), true) => Ok(Publicity::Internal { + attribute_location: Some(location), + }), (InternalAttribute::Present(location), false) => Err(ParseError { error: ParseErrorType::RedundantInternalAttribute, location, @@ -2298,7 +2369,12 @@ where self.advance(); if self.maybe_one(&Token::Dot).is_some() { let (_, upname, upname_e) = self.expect_upname()?; - self.parse_type_name_finish(start, Some(mod_name), upname, upname_e) + self.parse_type_name_finish( + start, + Some((mod_name, SrcSpan { start, end })), + upname, + upname_e, + ) } else { Ok(Some(TypeAst::Var(TypeAstVar { location: SrcSpan { start, end }, @@ -2318,7 +2394,7 @@ where fn parse_type_name_finish( &mut self, start: u32, - module: Option, + module: Option<(EcoString, SrcSpan)>, name: EcoString, end: u32, ) -> Result, ParseError> { @@ -2627,7 +2703,7 @@ where Ok(Some(Constant::List { elements, location: SrcSpan { start, end }, - typ: (), + type_: (), })) } // BitArray @@ -2658,14 +2734,21 @@ where self.parse_const_record_finish(start, None, name, end) } - Some((start, Token::Name { name }, _)) if self.peek_tok1() == Some(&Token::Dot) => { + Some((start, Token::Name { name }, module_end)) + if self.peek_tok1() == Some(&Token::Dot) => + { self.advance(); // name self.advance(); // dot match self.tok0.take() { Some((_, Token::UpName { name: upname }, end)) => { self.advance(); // upname - self.parse_const_record_finish(start, Some(name), upname, end) + self.parse_const_record_finish( + start, + Some((name, SrcSpan::new(start, module_end))), + upname, + end, + ) } Some((_, Token::Name { name: end_name }, end)) => { self.advance(); // name @@ -2680,10 +2763,10 @@ where ), _ => Ok(Some(Constant::Var { location: SrcSpan { start, end }, - module: Some(name), + module: Some((name, SrcSpan::new(start, module_end))), name: end_name, constructor: None, - typ: (), + type_: (), })), } } @@ -2717,7 +2800,7 @@ where module: None, name, constructor: None, - typ: (), + type_: (), })), } } @@ -2772,7 +2855,7 @@ where fn parse_const_record_finish( &mut self, start: u32, - module: Option, + module: Option<(EcoString, SrcSpan)>, name: EcoString, end: u32, ) -> Result, ParseError> { @@ -2787,7 +2870,7 @@ where name, args, tag: (), - typ: (), + type_: (), field_map: None, })) } else { @@ -2797,7 +2880,7 @@ where name, args: vec![], tag: (), - typ: (), + type_: (), field_map: None, })) } @@ -2854,7 +2937,7 @@ where constructor: None, module: None, name: label, - typ: (), + type_: (), }, })) } else { @@ -3071,7 +3154,18 @@ where // Else, handle as an unexpected token. let field = match token { Token::Name { name } => name, - _ => { + token => { + let hint = match (&token, self.tok0.take()) { + (&Token::Fn { .. }, _) + | (&Token::Pub, Some((_, Token::Fn { .. }, _))) => { + let text = + "Gleam is not an object oriented programming language so +functions are declared separately from types."; + Some(wrap(text).into()) + } + (_, _) => None, + }; + return parse_error( ParseErrorType::UnexpectedToken { token, @@ -3079,10 +3173,10 @@ where Token::RightBrace.to_string().into(), "a record constructor".into(), ], - hint: None, + hint, }, SrcSpan { start, end }, - ) + ); } }; let field_type = match self.parse_type_annotation(&Token::Colon) { @@ -3460,7 +3554,7 @@ where "erlang" => Target::Erlang, "javascript" => Target::JavaScript, "nix" => Target::Nix, - _ => return parse_error(ParseErrorType::UnknownAttribute, SrcSpan::new(start, end)), + _ => return parse_error(ParseErrorType::UnknownTarget, SrcSpan::new(start, end)), }; let _ = self.expect_one(&Token::Comma)?; @@ -3474,7 +3568,7 @@ where return parse_error(ParseErrorType::DuplicateAttribute, SrcSpan { start, end }); } - attributes.set_external_for(target, Some((module, function))); + attributes.set_external_for(target, Some((module, function, SrcSpan { start, end }))); Ok(end) } diff --git a/compiler-core/src/parse/error.rs b/compiler-core/src/parse/error.rs index e4e3af964..0c74c086d 100644 --- a/compiler-core/src/parse/error.rs +++ b/compiler-core/src/parse/error.rs @@ -239,7 +239,10 @@ utf16_codepoint, utf32_codepoint, signed, unsigned, big, little, native, size, u "Duplicate attribute", vec!["This attribute has already been given.".into()], ), - ParseErrorType::UnknownTarget => ("I don't know what this attribute is", vec![]), + ParseErrorType::UnknownTarget => ( + "I don't recognise this target", + vec!["Try `erlang`, `javascript`, `nix`.".into()], + ), ParseErrorType::ExpectedFunctionBody => ("This function does not have a body", vec![]), ParseErrorType::RedundantInternalAttribute => ( "Redundant internal attribute", @@ -292,6 +295,19 @@ utf16_codepoint, utf32_codepoint, signed, unsigned, big, little, native, size, u "Unsupported expression", vec!["Functions cannot be called in clause guards.".into()], ), + ParseErrorType::IfExpression => ( + "Gleam doesn't have if expressions", + vec![ + "If you want to write a conditional expression you can use a `case`:".into(), + "".into(), + " case condition {".into(), + " True -> todo".into(), + " False -> todo".into(), + " }".into(), + "".into(), + "See: https://tour.gleam.run/flow-control/case-expressions/".into(), + ], + ), } } } @@ -358,6 +374,7 @@ pub enum ParseErrorType { field_type: Option, }, CallInClauseGuard, // case x { _ if f() -> 1 } + IfExpression, } impl LexicalError { diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__const_string_concat.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__const_string_concat.snap index 3a2eda56d..d4eb5ce4b 100644 --- a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__const_string_concat.snap +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__const_string_concat.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/parse/tests.rs expression: "\nconst cute = \"cute\"\nconst cute_bee = cute <> \"bee\"\n" +snapshot_kind: text --- Parsed { module: Module { @@ -73,7 +74,7 @@ Parsed { module: None, name: "cute", constructor: None, - typ: (), + type_: (), }, right: String { location: SrcSpan { diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__error_message_on_variable_starting_with_underscore.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__error_message_on_variable_starting_with_underscore.snap new file mode 100644 index 000000000..910bd1f76 --- /dev/null +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__error_message_on_variable_starting_with_underscore.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/parse/tests.rs +expression: "\n pub fn main() {\n let val = _func_starting_with_underscore(1)\n }" +--- +error: Syntax error + ┌─ /src/parse/error.gleam:3:15 + │ +3 │ let val = _func_starting_with_underscore(1) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I'm expecting a lowercase name here + +Hint: Variable and module names start with a lowercase letter, and can +contain a-z, 0-9, or _. diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__error_message_on_variable_starting_with_underscore2.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__error_message_on_variable_starting_with_underscore2.snap new file mode 100644 index 000000000..0cb1f631c --- /dev/null +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__error_message_on_variable_starting_with_underscore2.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/parse/tests.rs +expression: "\n pub fn main() {\n case 1 {\n 1 -> _with_underscore(1)\n }\n }" +--- +error: Syntax error + ┌─ /src/parse/error.gleam:4:12 + │ +4 │ 1 -> _with_underscore(1) + │ ^^^^^^^^^^^^^^^^ I'm expecting a lowercase name here + +Hint: Variable and module names start with a lowercase letter, and can +contain a-z, 0-9, or _. diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__function_inside_a_type.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__function_inside_a_type.snap new file mode 100644 index 000000000..6f0240305 --- /dev/null +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__function_inside_a_type.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/parse/tests.rs +assertion_line: 1466 +expression: "\ntype Wibble {\n fn wobble() {}\n}\n" +--- +error: Syntax error + ┌─ /src/parse/error.gleam:3:3 + │ +3 │ fn wobble() {} + │ ^^ I was not expecting this + +Found the keyword `fn`, expected one of: +- `}` +- a record constructor +Hint: Gleam is not an object oriented programming language so +functions are declared separately from types. diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__if_like_expression.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__if_like_expression.snap new file mode 100644 index 000000000..f422ea673 --- /dev/null +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__if_like_expression.snap @@ -0,0 +1,18 @@ +--- +source: compiler-core/src/parse/tests.rs +expression: "\npub fn main() {\n let a = if wibble {\n wobble\n }\n}\n" +--- +error: Syntax error + ┌─ /src/parse/error.gleam:3:11 + │ +3 │ let a = if wibble { + │ ^^ Gleam doesn't have if expressions + +If you want to write a conditional expression you can use a `case`: + + case condition { + True -> todo + False -> todo + } + +See: https://tour.gleam.run/flow-control/case-expressions/ diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand.snap index 0f95fa2f9..077e4d878 100644 --- a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand.snap +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand.snap @@ -6,7 +6,7 @@ error: Syntax error ┌─ /src/parse/error.gleam:3:10 │ 3 │ wibble(:) - │ ^ There must be a 'let' to bind variable to value + │ ^ I was not expecting this -Hint: Use let for binding. -See: https://tour.gleam.run/basics/assignments/ +Found `:`, expected one of: +- `)` diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_2.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_2.snap index a6715b418..62c5e5f57 100644 --- a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_2.snap +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_2.snap @@ -6,7 +6,7 @@ error: Syntax error ┌─ /src/parse/error.gleam:3:10 │ 3 │ wibble(:,) - │ ^ There must be a 'let' to bind variable to value + │ ^ I was not expecting this -Hint: Use let for binding. -See: https://tour.gleam.run/basics/assignments/ +Found `:`, expected one of: +- `)` diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_3.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_3.snap index 93d7cf3a5..a9af948dd 100644 --- a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_3.snap +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_3.snap @@ -6,7 +6,7 @@ error: Syntax error ┌─ /src/parse/error.gleam:3:10 │ 3 │ wibble(:arg) - │ ^ There must be a 'let' to bind variable to value + │ ^ I was not expecting this -Hint: Use let for binding. -See: https://tour.gleam.run/basics/assignments/ +Found `:`, expected one of: +- `)` diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_4.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_4.snap index b24ccc489..73ccdee8f 100644 --- a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_4.snap +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_4.snap @@ -6,7 +6,7 @@ error: Syntax error ┌─ /src/parse/error.gleam:3:14 │ 3 │ wibble(arg::) - │ ^ There must be a 'let' to bind variable to value + │ ^ I was not expecting this -Hint: Use let for binding. -See: https://tour.gleam.run/basics/assignments/ +Found `:`, expected one of: +- `)` diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_5.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_5.snap index ba5f7cb34..ca8764038 100644 --- a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_5.snap +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__invalid_label_shorthand_5.snap @@ -6,7 +6,7 @@ error: Syntax error ┌─ /src/parse/error.gleam:3:14 │ 3 │ wibble(arg::arg) - │ ^ There must be a 'let' to bind variable to value + │ ^ I was not expecting this -Hint: Use let for binding. -See: https://tour.gleam.run/basics/assignments/ +Found `:`, expected one of: +- `)` diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__non_module_level_function_with_a_name.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__non_module_level_function_with_a_name.snap new file mode 100644 index 000000000..026513941 --- /dev/null +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__non_module_level_function_with_a_name.snap @@ -0,0 +1,13 @@ +--- +source: compiler-core/src/parse/tests.rs +expression: "\npub fn main() {\n fn my() { 1 }\n}\n" +--- +error: Syntax error + ┌─ /src/parse/error.gleam:3:6 + │ +3 │ fn my() { 1 } + │ ^^ I was not expecting this + +Found a name, expected one of: +- `(` +Hint: Only module-level functions can be named. diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__non_module_level_function_with_not_a_name.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__non_module_level_function_with_not_a_name.snap new file mode 100644 index 000000000..9b6536a50 --- /dev/null +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__non_module_level_function_with_not_a_name.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/parse/tests.rs +expression: "\npub fn main() {\n fn @() { 1 } // wrong token and not a name\n}\n" +--- +error: Syntax error + ┌─ /src/parse/error.gleam:3:6 + │ +3 │ fn @() { 1 } // wrong token and not a name + │ ^ I was not expecting this + +Found `@`, expected one of: +- `(` diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__pub_function_inside_a_type.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__pub_function_inside_a_type.snap new file mode 100644 index 000000000..a995317b7 --- /dev/null +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__pub_function_inside_a_type.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/parse/tests.rs +assertion_line: 1477 +expression: "\ntype Wibble {\n pub fn wobble() {}\n}\n" +--- +error: Syntax error + ┌─ /src/parse/error.gleam:3:3 + │ +3 │ pub fn wobble() {} + │ ^^^ I was not expecting this + +Found the keyword `pub`, expected one of: +- `}` +- a record constructor +Hint: Gleam is not an object oriented programming language so +functions are declared separately from types. diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__unknown_external_target.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__unknown_external_target.snap new file mode 100644 index 000000000..33d9f3960 --- /dev/null +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__unknown_external_target.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/parse/tests.rs +expression: "\n@external(erl, \"one\", \"two\")\npub fn one(x: Int) -> Int {\n todo\n}" +snapshot_kind: text +--- +error: Syntax error + ┌─ /src/parse/error.gleam:2:1 + │ +2 │ @external(erl, "one", "two") + │ ^^^^^^^^^ I don't recognise this target + +Try `erlang`, `javascript`, `nix`. diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__with_let_binding3.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__with_let_binding3.snap new file mode 100644 index 000000000..767bf8c42 --- /dev/null +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__with_let_binding3.snap @@ -0,0 +1,55 @@ +--- +source: compiler-core/src/parse/tests.rs +expression: "let assert [x] = [2]" +--- +[ + Assignment( + Assignment { + location: SrcSpan { + start: 0, + end: 20, + }, + value: List { + location: SrcSpan { + start: 17, + end: 20, + }, + elements: [ + Int { + location: SrcSpan { + start: 18, + end: 19, + }, + value: "2", + }, + ], + tail: None, + }, + pattern: List { + location: SrcSpan { + start: 11, + end: 14, + }, + elements: [ + Variable { + location: SrcSpan { + start: 12, + end: 13, + }, + name: "x", + type_: (), + }, + ], + tail: None, + type_: (), + }, + kind: Assert { + location: SrcSpan { + start: 4, + end: 10, + }, + }, + annotation: None, + }, + ), +] diff --git a/compiler-core/src/parse/snapshots/glistix_core__parse__tests__with_let_binding3_and_annotation.snap b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__with_let_binding3_and_annotation.snap new file mode 100644 index 000000000..037d3a8ab --- /dev/null +++ b/compiler-core/src/parse/snapshots/glistix_core__parse__tests__with_let_binding3_and_annotation.snap @@ -0,0 +1,79 @@ +--- +source: compiler-core/src/parse/tests.rs +expression: "let assert [x]: List(Int) = [2]" +--- +[ + Assignment( + Assignment { + location: SrcSpan { + start: 0, + end: 31, + }, + value: List { + location: SrcSpan { + start: 28, + end: 31, + }, + elements: [ + Int { + location: SrcSpan { + start: 29, + end: 30, + }, + value: "2", + }, + ], + tail: None, + }, + pattern: List { + location: SrcSpan { + start: 11, + end: 14, + }, + elements: [ + Variable { + location: SrcSpan { + start: 12, + end: 13, + }, + name: "x", + type_: (), + }, + ], + tail: None, + type_: (), + }, + kind: Assert { + location: SrcSpan { + start: 4, + end: 10, + }, + }, + annotation: Some( + Constructor( + TypeAstConstructor { + location: SrcSpan { + start: 16, + end: 25, + }, + module: None, + name: "List", + arguments: [ + Constructor( + TypeAstConstructor { + location: SrcSpan { + start: 21, + end: 24, + }, + module: None, + name: "Int", + arguments: [], + }, + ), + ], + }, + ), + ), + }, + ), +] diff --git a/compiler-core/src/parse/tests.rs b/compiler-core/src/parse/tests.rs index 87d573c4e..d90e78b9e 100644 --- a/compiler-core/src/parse/tests.rs +++ b/compiler-core/src/parse/tests.rs @@ -343,8 +343,8 @@ fn triple_equals_with_whitespace() { "let wobble:Int = 32 wobble == = 42", ParseError { - error: ParseErrorType::NoLetBinding, - location: SrcSpan { start: 42, end: 43 }, + error: ParseErrorType::OpNakedRight, + location: SrcSpan { start: 35, end: 37 }, } ); } @@ -432,6 +432,17 @@ fn no_let_binding3() { ); } +#[test] +fn with_let_binding3() { + // The same with `let assert` must parse: + assert_parse!("let assert [x] = [2]"); +} + +#[test] +fn with_let_binding3_and_annotation() { + assert_parse!("let assert [x]: List(Int) = [2]"); +} + #[test] fn no_eq_after_binding() { assert_error!( @@ -579,6 +590,17 @@ pub fn one(x: Int) -> Int { ); } +#[test] +fn unknown_external_target() { + assert_module_error!( + r#" +@external(erl, "one", "two") +pub fn one(x: Int) -> Int { + todo +}"# + ); +} + #[test] fn unknown_attribute() { assert_module_error!( @@ -1403,3 +1425,84 @@ fn doc_comment_before_comment_is_not_attached_to_following_constant() { " Doc!\n" ); } + +#[test] +fn non_module_level_function_with_a_name() { + assert_module_error!( + r#" +pub fn main() { + fn my() { 1 } +} +"# + ); +} + +#[test] +fn error_message_on_variable_starting_with_underscore() { + // https://github.com/gleam-lang/gleam/issues/3504 + assert_module_error!( + " + pub fn main() { + let val = _func_starting_with_underscore(1) + }" + ); +} + +#[test] +fn non_module_level_function_with_not_a_name() { + assert_module_error!( + r#" +pub fn main() { + fn @() { 1 } // wrong token and not a name +} +"# + ); +} + +#[test] +fn error_message_on_variable_starting_with_underscore2() { + // https://github.com/gleam-lang/gleam/issues/3504 + assert_module_error!( + " + pub fn main() { + case 1 { + 1 -> _with_underscore(1) + } + }" + ); +} + +#[test] +fn function_inside_a_type() { + assert_module_error!( + r#" +type Wibble { + fn wobble() {} +} +"# + ); +} + +#[test] +fn pub_function_inside_a_type() { + assert_module_error!( + r#" +type Wibble { + pub fn wobble() {} +} +"# + ); +} + +#[test] +fn if_like_expression() { + assert_module_error!( + r#" +pub fn main() { + let a = if wibble { + wobble + } +} +"# + ); +} diff --git a/compiler-core/src/type_.rs b/compiler-core/src/type_.rs index 7302776db..4d987298c 100644 --- a/compiler-core/src/type_.rs +++ b/compiler-core/src/type_.rs @@ -17,6 +17,7 @@ pub use environment::*; pub use error::{Error, Problems, UnifyErrorSituation, Warning}; pub(crate) use expression::ExprTyper; pub use fields::FieldMap; +use hexpm::version::Version; pub use prelude::*; use serde::Serialize; @@ -100,21 +101,21 @@ impl Type { pub fn is_unbound(&self) -> bool { match self { - Self::Var { type_: typ } => typ.borrow().is_unbound(), + Self::Var { type_ } => type_.borrow().is_unbound(), _ => false, } } pub fn is_variable(&self) -> bool { match self { - Self::Var { type_: typ } => typ.borrow().is_variable(), + Self::Var { type_ } => type_.borrow().is_variable(), _ => false, } } pub fn is_type_variable(&self) -> bool { match self { - Self::Var { type_: typ } => typ.borrow().is_variable(), + Self::Var { type_ } => type_.borrow().is_variable(), _ => false, } } @@ -253,10 +254,10 @@ impl Type { } } - Self::Var { type_: typ } => { - let args: Vec<_> = match typ.borrow().deref() { - TypeVar::Link { type_: typ } => { - return typ.get_app_args( + Self::Var { type_ } => { + let args: Vec<_> = match type_.borrow().deref() { + TypeVar::Link { type_ } => { + return type_.get_app_args( publicity, package, module, @@ -275,7 +276,7 @@ impl Type { // We are an unbound type variable! So convert us to a type link // to the desired type. - *typ.borrow_mut() = TypeVar::Link { + *type_.borrow_mut() = TypeVar::Link { type_: Arc::new(Self::Named { name: name.into(), package: package.into(), @@ -306,12 +307,12 @@ impl Type { .find_private_type() .or_else(|| args.iter().find_map(|t| t.find_private_type())), - Self::Var { type_: typ, .. } => match typ.borrow().deref() { + Self::Var { type_, .. } => match type_.borrow().deref() { TypeVar::Unbound { .. } => None, TypeVar::Generic { .. } => None, - TypeVar::Link { type_: typ, .. } => typ.find_private_type(), + TypeVar::Link { type_, .. } => type_.find_private_type(), }, } } @@ -328,9 +329,9 @@ impl Type { .find_internal_type() .or_else(|| args.iter().find_map(|t| t.find_internal_type())), - Self::Var { type_: typ, .. } => match typ.borrow().deref() { + Self::Var { type_, .. } => match type_.borrow().deref() { TypeVar::Unbound { .. } | TypeVar::Generic { .. } => None, - TypeVar::Link { type_: typ, .. } => typ.find_internal_type(), + TypeVar::Link { type_, .. } => type_.find_internal_type(), }, } } @@ -344,9 +345,9 @@ impl Type { } pub fn collapse_links(t: Arc) -> Arc { - if let Type::Var { type_: typ } = t.deref() { - if let TypeVar::Link { type_: typ } = typ.borrow().deref() { - return collapse_links(typ.clone()); + if let Type::Var { type_ } = t.deref() { + if let TypeVar::Link { type_ } = type_.borrow().deref() { + return collapse_links(type_.clone()); } } t @@ -395,6 +396,9 @@ pub enum ValueConstructorVariant { location: SrcSpan, documentation: Option, implementations: Implementations, + external_erlang: Option<(EcoString, EcoString)>, + external_javascript: Option<(EcoString, EcoString)>, + external_nix: Option<(EcoString, EcoString)>, }, /// A constructor for a custom type @@ -455,6 +459,9 @@ impl ValueConstructorVariant { Self::LocalVariable { location, .. } => ModuleValueConstructor::Fn { name: function_name.clone(), module: module_name.clone(), + external_erlang: None, + external_javascript: None, + external_nix: None, documentation: None, location: *location, field_map: None, @@ -466,11 +473,17 @@ impl ValueConstructorVariant { location, documentation, field_map, + external_erlang, + external_javascript, + external_nix, .. } => ModuleValueConstructor::Fn { name: name.clone(), module: module.clone(), documentation: documentation.clone(), + external_erlang: external_erlang.clone(), + external_javascript: external_javascript.clone(), + external_nix: external_nix.clone(), location: *location, field_map: field_map.clone(), }, @@ -545,20 +558,24 @@ pub enum ModuleValueConstructor { Fn { location: SrcSpan, /// The name of the module and the function - /// Typically this will be the module that this constructor belongs to - /// and the name that was used for the function. However it could also - /// point to some other module and function when this is an `external` - /// function. + /// This will be the module that this constructor belongs to + /// and the name that was used for the function. + module: EcoString, + name: EcoString, + /// If this is an `external` function, these will hold the name of the + /// external module and function. /// /// This function has module "themodule" and name "wibble" /// pub fn wibble() { Nil } /// - /// This function has module "other" and name "whoop" + /// This function has module "themodule" and name "wibble" + /// and erlang external "other" and "whoop". /// @external(erlang, "other", "whoop") /// pub fn wibble() -> Nil /// - module: EcoString, - name: EcoString, + external_erlang: Option<(EcoString, EcoString)>, + external_javascript: Option<(EcoString, EcoString)>, + external_nix: Option<(EcoString, EcoString)>, field_map: Option, documentation: Option, }, @@ -602,7 +619,6 @@ pub struct ModuleInterface { pub types_value_constructors: HashMap, pub values: HashMap, pub accessors: HashMap, - pub unused_imports: Vec, /// Used for mapping to original source locations on disk pub line_numbers: LineNumbers, /// Used for determining the source path of the module on disk @@ -613,6 +629,8 @@ pub struct ModuleInterface { pub is_internal: bool, /// Warnings emitted during analysis of this module. pub warnings: Vec, + /// The minimum Gleam version needed to use this module. + pub minimum_required_version: Version, } impl ModuleInterface { @@ -656,7 +674,7 @@ impl TypeVariantConstructors { .expect("Type parameter not found in hydrator"); let error = "Hydrator must not store non generic types here"; match t.type_.as_ref() { - Type::Var { type_: typ } => match typ.borrow().deref() { + Type::Var { type_ } => match type_.borrow().deref() { TypeVar::Generic { id } => *id, _ => panic!("{}", error), }, @@ -684,29 +702,6 @@ pub struct TypeValueConstructorField { } impl ModuleInterface { - pub fn new( - name: EcoString, - origin: Origin, - package: EcoString, - line_numbers: LineNumbers, - src_path: Utf8PathBuf, - ) -> Self { - Self { - name, - origin, - package, - types: Default::default(), - types_value_constructors: Default::default(), - values: Default::default(), - accessors: Default::default(), - unused_imports: Default::default(), - is_internal: false, - line_numbers, - src_path, - warnings: vec![], - } - } - pub fn get_public_value(&self, name: &str) -> Option<&ValueConstructor> { let value = self.values.get(name)?; if value.publicity.is_importable() { @@ -912,7 +907,7 @@ pub struct TypeConstructor { pub origin: SrcSpan, pub module: EcoString, pub parameters: Vec>, - pub typ: Arc, + pub type_: Arc, pub deprecation: Deprecation, pub documentation: Option, } @@ -965,6 +960,9 @@ impl ValueConstructor { } | ValueConstructorVariant::ModuleConstant { location, module, .. + } + | ValueConstructorVariant::ModuleFn { + location, module, .. } => DefinitionLocation { module: Some(module.as_str()), span: *location, @@ -975,8 +973,7 @@ impl ValueConstructor { span: literal.location(), }, - ValueConstructorVariant::ModuleFn { location, .. } - | ValueConstructorVariant::LocalVariable { location } => DefinitionLocation { + ValueConstructorVariant::LocalVariable { location } => DefinitionLocation { module: None, span: *location, }, @@ -1035,10 +1032,10 @@ fn assert_no_labelled_arguments(args: &[CallArg]) -> Result<(), Error> { /// could cause naively-implemented type checking to diverge. /// While traversing the type tree. /// -fn unify_unbound_type(typ: Arc, own_id: u64) -> Result<(), UnifyError> { - if let Type::Var { type_: typ } = typ.deref() { - let new_value = match typ.borrow().deref() { - TypeVar::Link { type_: typ, .. } => return unify_unbound_type(typ.clone(), own_id), +fn unify_unbound_type(type_: Arc, own_id: u64) -> Result<(), UnifyError> { + if let Type::Var { type_ } = type_.deref() { + let new_value = match type_.borrow().deref() { + TypeVar::Link { type_, .. } => return unify_unbound_type(type_.clone(), own_id), TypeVar::Unbound { id } => { if id == &own_id { @@ -1052,12 +1049,12 @@ fn unify_unbound_type(typ: Arc, own_id: u64) -> Result<(), UnifyError> { }; if let Some(t) = new_value { - *typ.borrow_mut() = t; + *type_.borrow_mut() = t; } return Ok(()); } - match typ.deref() { + match type_.deref() { Type::Named { args, .. } => { for arg in args { unify_unbound_type(arg.clone(), own_id)? @@ -1084,14 +1081,14 @@ fn unify_unbound_type(typ: Arc, own_id: u64) -> Result<(), UnifyError> { } fn match_fun_type( - typ: Arc, + type_: Arc, arity: usize, environment: &mut Environment<'_>, ) -> Result<(Vec>, Arc), MatchFunTypeError> { - if let Type::Var { type_: typ } = typ.deref() { - let new_value = match typ.borrow().deref() { - TypeVar::Link { type_: typ, .. } => { - return match_fun_type(typ.clone(), arity, environment); + if let Type::Var { type_ } = type_.deref() { + let new_value = match type_.borrow().deref() { + TypeVar::Link { type_, .. } => { + return match_fun_type(type_.clone(), arity, environment); } TypeVar::Unbound { .. } => { @@ -1104,14 +1101,14 @@ fn match_fun_type( }; if let Some((args, retrn)) = new_value { - *typ.borrow_mut() = TypeVar::Link { + *type_.borrow_mut() = TypeVar::Link { type_: fn_(args.clone(), retrn.clone()), }; return Ok((args, retrn)); } } - if let Type::Fn { args, retrn } = typ.deref() { + if let Type::Fn { args, retrn } = type_.deref() { return if args.len() != arity { Err(MatchFunTypeError::IncorrectArity { expected: args.len(), @@ -1124,15 +1121,17 @@ fn match_fun_type( }; } - Err(MatchFunTypeError::NotFn { typ }) + Err(MatchFunTypeError::NotFn { type_ }) } pub fn generalise(t: Arc) -> Arc { match t.deref() { - Type::Var { type_: typ } => match typ.borrow().deref() { + Type::Var { type_ } => match type_.borrow().deref() { TypeVar::Unbound { id } => generic_var(*id), - TypeVar::Link { type_: typ } => generalise(typ.clone()), - TypeVar::Generic { .. } => Arc::new(Type::Var { type_: typ.clone() }), + TypeVar::Link { type_ } => generalise(type_.clone()), + TypeVar::Generic { .. } => Arc::new(Type::Var { + type_: type_.clone(), + }), }, Type::Named { diff --git a/compiler-core/src/type_/environment.rs b/compiler-core/src/type_/environment.rs index 6505e8667..c8dab64ba 100644 --- a/compiler-core/src/type_/environment.rs +++ b/compiler-core/src/type_/environment.rs @@ -1,7 +1,11 @@ +use pubgrub::range::Range; + use crate::{ analyse::TargetSupport, ast::{Publicity, PIPE_VARIABLE}, build::Target, + error::edit_distance, + exhaustiveness::printer::ValueNames, uid::UniqueIdGenerator, }; @@ -11,6 +15,11 @@ use std::collections::HashMap; #[derive(Debug)] pub struct Environment<'a> { pub current_package: EcoString, + + /// The gleam version range required by the current package as stated in its + /// gleam.toml + pub gleam_version: Option>, + pub current_module: EcoString, pub target: Target, pub ids: UniqueIdGenerator, @@ -54,12 +63,15 @@ pub struct Environment<'a> { /// Used to determine if all functions/constants need to support the current /// compilation target. pub target_support: TargetSupport, + + pub value_names: ValueNames, } impl<'a> Environment<'a> { pub fn new( ids: UniqueIdGenerator, current_package: EcoString, + gleam_version: Option>, current_module: EcoString, target: Target, importable_modules: &'a im::HashMap, @@ -68,8 +80,19 @@ impl<'a> Environment<'a> { let prelude = importable_modules .get(PRELUDE_MODULE_NAME) .expect("Unable to find prelude in importable modules"); + + let mut value_names = ValueNames::new(); + for name in prelude.values.keys() { + value_names.named_constructor_in_scope( + PRELUDE_MODULE_NAME.into(), + name.clone(), + name.clone(), + ); + } + Self { current_package: current_package.clone(), + gleam_version, previous_id: ids.next(), ids, target, @@ -88,6 +111,7 @@ impl<'a> Environment<'a> { current_module, entity_usages: vec![HashMap::new()], target_support, + value_names, } } } @@ -120,7 +144,7 @@ pub struct ScopeResetData { local_values: im::HashMap, } -impl<'a> Environment<'a> { +impl Environment<'_> { pub fn in_new_scope( &mut self, problems: &mut Problems, @@ -190,14 +214,14 @@ impl<'a> Environment<'a> { /// Insert a variable in the current scope. /// - pub fn insert_local_variable(&mut self, name: EcoString, location: SrcSpan, typ: Arc) { + pub fn insert_local_variable(&mut self, name: EcoString, location: SrcSpan, type_: Arc) { let _ = self.scope.insert( name, ValueConstructor { deprecation: Deprecation::NotDeprecated, publicity: Publicity::Private, variant: ValueConstructorVariant::LocalVariable { location }, - type_: typ, + type_, }, ); } @@ -227,7 +251,7 @@ impl<'a> Environment<'a> { &mut self, name: EcoString, variant: ValueConstructorVariant, - typ: Arc, + type_: Arc, publicity: Publicity, deprecation: Deprecation, ) { @@ -237,7 +261,7 @@ impl<'a> Environment<'a> { publicity, deprecation, variant, - type_: typ, + type_, }, ); } @@ -319,7 +343,7 @@ impl<'a> Environment<'a> { /// pub fn get_type_constructor( &mut self, - module_alias: &Option, + module_alias: &Option<(EcoString, SrcSpan)>, name: &EcoString, ) -> Result<&TypeConstructor, UnknownTypeConstructorError> { let t = match module_alias { @@ -331,11 +355,12 @@ impl<'a> Environment<'a> { hint: self.unknown_type_hint(name), }), - Some(module_name) => { + Some((module_name, _)) => { let (_, module) = self.imported_modules.get(module_name).ok_or_else(|| { UnknownTypeConstructorError::Module { name: module_name.clone(), - imported_modules: self.importable_modules.keys().cloned().collect(), + suggestions: self + .suggest_modules(module_name, Imported::Type(name.clone())), } })?; let _ = self.unused_modules.remove(module_name); @@ -386,7 +411,7 @@ impl<'a> Environment<'a> { let module = self.importable_modules.get(m).ok_or_else(|| { UnknownTypeConstructorError::Module { name: name.clone(), - imported_modules: self.importable_modules.keys().cloned().collect(), + suggestions: self.suggest_modules(m, Imported::Type(name.clone())), } })?; module.types_value_constructors.get(name).ok_or_else(|| { @@ -410,7 +435,7 @@ impl<'a> Environment<'a> { ) -> Result<&ValueConstructor, UnknownValueConstructorError> { match module { None => self.scope.get(name).ok_or_else(|| { - let type_with_name_in_scope = self.module_types.keys().any(|typ| typ == name); + let type_with_name_in_scope = self.module_types.keys().any(|type_| type_ == name); UnknownValueConstructorError::Variable { name: name.clone(), variables: self.local_value_names(), @@ -422,7 +447,8 @@ impl<'a> Environment<'a> { let (_, module) = self.imported_modules.get(module_name).ok_or_else(|| { UnknownValueConstructorError::Module { name: module_name.clone(), - imported_modules: self.importable_modules.keys().cloned().collect(), + suggestions: self + .suggest_modules(module_name, Imported::Value(name.clone())), } })?; let _ = self.unused_modules.remove(module_name); @@ -472,13 +498,17 @@ impl<'a> Environment<'a> { }) } - Type::Var { type_: typ } => { - match typ.borrow().deref() { - TypeVar::Link { type_: typ } => { - return self.instantiate(typ.clone(), ids, hydrator) + Type::Var { type_ } => { + match type_.borrow().deref() { + TypeVar::Link { type_ } => { + return self.instantiate(type_.clone(), ids, hydrator) } - TypeVar::Unbound { .. } => return Arc::new(Type::Var { type_: typ.clone() }), + TypeVar::Unbound { .. } => { + return Arc::new(Type::Var { + type_: type_.clone(), + }) + } TypeVar::Generic { id } => match ids.get(id) { Some(t) => return t.clone(), @@ -492,7 +522,9 @@ impl<'a> Environment<'a> { } }, } - Arc::new(Type::Var { type_: typ.clone() }) + Arc::new(Type::Var { + type_: type_.clone(), + }) } Type::Fn { args, retrn, .. } => fn_( @@ -569,20 +601,18 @@ impl<'a> Environment<'a> { /// Converts entities with a usage count of 0 to warnings. /// Returns the list of unused imported module location for the removed unused lsp action. - pub fn convert_unused_to_warnings(&mut self, problems: &mut Problems) -> Vec { + pub fn convert_unused_to_warnings(&mut self, problems: &mut Problems) { let unused = self .entity_usages .pop() .expect("Expected a bottom level of entity usages."); self.handle_unused(unused, problems); - let mut locations = Vec::new(); for (name, location) in self.unused_modules.clone().into_iter() { problems.warning(Warning::UnusedImportedModule { name: name.clone(), location, }); - locations.push(location); } for (name, info) in self.unused_module_aliases.iter() { @@ -592,10 +622,8 @@ impl<'a> Environment<'a> { location: info.location, module_name: info.module_name.clone(), }); - locations.push(info.location); } } - locations } fn handle_unused( @@ -647,6 +675,63 @@ impl<'a> Environment<'a> { .cloned() .collect() } + + /// Suggest modules to import or use, for an unknown module + pub fn suggest_modules(&self, module: &str, imported: Imported) -> Vec { + let mut suggestions = self + .importable_modules + .iter() + .filter_map(|(importable, module_info)| { + match &imported { + // Don't suggest importing modules if they are already imported + _ if self + .imported_modules + .contains_key(importable.split('/').last().unwrap_or(importable)) => + { + None + } + Imported::Type(name) if module_info.get_public_type(name).is_some() => { + Some(ModuleSuggestion::Importable(importable.clone())) + } + Imported::Value(name) if module_info.get_public_value(name).is_some() => { + Some(ModuleSuggestion::Importable(importable.clone())) + } + _ => None, + } + }) + .collect_vec(); + + suggestions.extend( + self.imported_modules + .keys() + .map(|module| ModuleSuggestion::Imported(module.clone())), + ); + + let threshold = std::cmp::max(module.chars().count() / 3, 1); + + // Filter and sort options based on edit distance. + suggestions + .into_iter() + .sorted() + .filter_map(|suggestion| { + edit_distance(module, suggestion.last_name_component(), threshold) + .map(|distance| (suggestion, distance)) + }) + .sorted_by_key(|&(_, distance)| distance) + .map(|(suggestion, _)| suggestion) + .collect() + } +} + +#[derive(Debug)] +/// An imported name, for looking up a module which exports it +pub enum Imported { + /// An imported module, with no extra information + Module, + /// An imported type + Type(EcoString), + /// An imported value + Value(EcoString), } /// Unify two types that should be the same. @@ -660,21 +745,21 @@ pub fn unify(t1: Arc, t2: Arc) -> Result<(), UnifyError> { } // Collapse right hand side type links. Left hand side will be collapsed in the next block. - if let Type::Var { type_: typ } = t2.deref() { - if let TypeVar::Link { type_: typ } = typ.borrow().deref() { - return unify(t1, typ.clone()); + if let Type::Var { type_ } = t2.deref() { + if let TypeVar::Link { type_ } = type_.borrow().deref() { + return unify(t1, type_.clone()); } } - if let Type::Var { type_: typ } = t1.deref() { + if let Type::Var { type_ } = t1.deref() { enum Action { Unify(Arc), CouldNotUnify, Link, } - let action = match typ.borrow().deref() { - TypeVar::Link { type_: typ } => Action::Unify(typ.clone()), + let action = match type_.borrow().deref() { + TypeVar::Link { type_ } => Action::Unify(type_.clone()), TypeVar::Unbound { id } => { unify_unbound_type(t2.clone(), *id)?; @@ -682,9 +767,9 @@ pub fn unify(t1: Arc, t2: Arc) -> Result<(), UnifyError> { } TypeVar::Generic { id } => { - if let Type::Var { type_: typ } = t2.deref() { - if typ.borrow().is_unbound() { - *typ.borrow_mut() = TypeVar::Generic { id: *id }; + if let Type::Var { type_ } = t2.deref() { + if type_.borrow().is_unbound() { + *type_.borrow_mut() = TypeVar::Generic { id: *id }; return Ok(()); } } @@ -694,7 +779,7 @@ pub fn unify(t1: Arc, t2: Arc) -> Result<(), UnifyError> { return match action { Action::Link => { - *typ.borrow_mut() = TypeVar::Link { type_: t2 }; + *type_.borrow_mut() = TypeVar::Link { type_: t2 }; Ok(()) } diff --git a/compiler-core/src/type_/error.rs b/compiler-core/src/type_/error.rs index fa4cecb84..694ab5c60 100644 --- a/compiler-core/src/type_/error.rs +++ b/compiler-core/src/type_/error.rs @@ -10,6 +10,7 @@ use crate::{ use camino::Utf8PathBuf; use ecow::EcoString; +use hexpm::version::Version; #[cfg(test)] use pretty_assertions::assert_eq; use std::sync::Arc; @@ -40,7 +41,7 @@ impl Problems { self.errors.push(error) } - /// Register an warning. + /// Register a warning. /// pub fn warning(&mut self, warning: Warning) { self.warnings.push(warning) @@ -71,6 +72,47 @@ pub enum RecordVariants { NoVariants, } +/// A suggestion for an unknown module +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub enum ModuleSuggestion { + /// A module which which has a similar name, and an + /// exported value matching the one being accessed + Importable(EcoString), + /// A module already imported in the current scope + Imported(EcoString), +} + +impl ModuleSuggestion { + pub fn suggestion(&self, module: &str) -> String { + match self { + ModuleSuggestion::Importable(name) => { + // Add a little extra information if the names don't match + let imported_name = self.last_name_component(); + if module == imported_name { + format!("Did you mean to import `{name}`?") + } else { + format!("Did you mean to import `{name}` and reference `{imported_name}`?") + } + } + ModuleSuggestion::Imported(name) => format!("Did you mean `{name}`?"), + } + } + + pub fn name(&self) -> &EcoString { + match self { + ModuleSuggestion::Imported(name) | ModuleSuggestion::Importable(name) => name, + } + } + + pub fn last_name_component(&self) -> &str { + match self { + ModuleSuggestion::Imported(name) | ModuleSuggestion::Importable(name) => { + name.split('/').last().unwrap_or(name) + } + } + } +} + #[derive(Debug, Eq, PartialEq, Clone)] pub enum Error { SrcImportingTest { @@ -106,7 +148,7 @@ pub enum Error { UnknownModule { location: SrcSpan, name: EcoString, - imported_modules: Vec, + suggestions: Vec, }, UnknownModuleType { @@ -125,14 +167,19 @@ pub enum Error { type_with_same_name: bool, }, + ModuleAliasUsedAsName { + location: SrcSpan, + name: EcoString, + }, + NotFn { location: SrcSpan, - typ: Arc, + type_: Arc, }, UnknownRecordField { location: SrcSpan, - typ: Arc, + type_: Arc, label: EcoString, fields: Vec, usage: FieldAccessUsage, @@ -437,7 +484,7 @@ pub enum Error { /// ``` NotFnInUse { location: SrcSpan, - typ: Arc, + type_: Arc, }, /// When the function to the right hand side of `<-` in a `use` expression @@ -557,7 +604,7 @@ pub enum Warning { Todo { kind: TodoKind, location: SrcSpan, - typ: Arc, + type_: Arc, }, ImplicitlyDiscardedResult { @@ -755,6 +802,48 @@ pub enum Warning { RedundantPipeFunctionCapture { location: SrcSpan, }, + + /// When the `gleam` range specified in the package's `gleam.toml` is too + /// low and would include a version that's too low to support this feature. + /// + /// For example, let's say that a package is saying `gleam = ">=1.1.0"` + /// but it is using label shorthand syntax: `wibble(label:)`. + /// That requires a version that is `>=1.4.0`, so the constraint expressed + /// in the `gleam.toml` is too permissive and if someone were to run this + /// code with v1.1.0 they would run into compilation errors since the + /// compiler cannot know of label shorthands! + /// + FeatureRequiresHigherGleamVersion { + location: SrcSpan, + minimum_required_version: Version, + wrongfully_allowed_version: Version, + feature_kind: FeatureKind, + }, +} + +#[derive(Debug, Eq, Copy, PartialEq, Clone, serde::Serialize, serde::Deserialize)] +pub enum FeatureKind { + LabelShorthandSyntax, + ConstantStringConcatenation, + ArithmeticInGuards, + UnannotatedUtf8StringSegment, + NestedTupleAccess, + InternalAnnotation, + AtInJavascriptModules, +} + +impl FeatureKind { + pub fn required_version(&self) -> Version { + match self { + FeatureKind::InternalAnnotation => Version::new(1, 1, 0), + FeatureKind::NestedTupleAccess => Version::new(1, 1, 0), + FeatureKind::AtInJavascriptModules => Version::new(1, 2, 0), + FeatureKind::ArithmeticInGuards => Version::new(1, 3, 0), + FeatureKind::LabelShorthandSyntax => Version::new(1, 4, 0), + FeatureKind::ConstantStringConcatenation => Version::new(1, 4, 0), + FeatureKind::UnannotatedUtf8StringSegment => Version::new(1, 5, 0), + } + } } #[derive(Debug, Eq, PartialEq, Clone, Copy, serde::Serialize, serde::Deserialize)] @@ -788,6 +877,7 @@ impl Error { | Error::UnknownModule { location, .. } | Error::UnknownModuleType { location, .. } | Error::UnknownModuleValue { location, .. } + | Error::ModuleAliasUsedAsName { location, .. } | Error::NotFn { location, .. } | Error::UnknownRecordField { location, .. } | Error::IncorrectArity { location, .. } @@ -914,7 +1004,8 @@ impl Warning { | Warning::RedundantAssertAssignment { location, .. } | Warning::TodoOrPanicUsedAsFunction { location, .. } | Warning::UnreachableCodeAfterPanic { location, .. } - | Warning::RedundantPipeFunctionCapture { location, .. } => *location, + | Warning::RedundantPipeFunctionCapture { location, .. } + | Warning::FeatureRequiresHigherGleamVersion { location, .. } => *location, } } @@ -936,7 +1027,7 @@ pub enum UnknownValueConstructorError { Module { name: EcoString, - imported_modules: Vec, + suggestions: Vec, }, ModuleValue { @@ -950,6 +1041,7 @@ pub enum UnknownValueConstructorError { pub fn convert_get_value_constructor_error( e: UnknownValueConstructorError, location: SrcSpan, + module_location: Option, ) -> Error { match e { UnknownValueConstructorError::Variable { @@ -963,13 +1055,10 @@ pub fn convert_get_value_constructor_error( type_with_name_in_scope, }, - UnknownValueConstructorError::Module { + UnknownValueConstructorError::Module { name, suggestions } => Error::UnknownModule { + location: module_location.unwrap_or(location), name, - imported_modules, - } => Error::UnknownModule { - location, - name, - imported_modules, + suggestions, }, UnknownValueConstructorError::ModuleValue { @@ -1002,7 +1091,7 @@ pub enum UnknownTypeConstructorError { Module { name: EcoString, - imported_modules: Vec, + suggestions: Vec, }, ModuleType { @@ -1016,6 +1105,7 @@ pub enum UnknownTypeConstructorError { pub fn convert_get_type_constructor_error( e: UnknownTypeConstructorError, location: &SrcSpan, + module_location: Option, ) -> Error { match e { UnknownTypeConstructorError::Type { name, hint } => Error::UnknownType { @@ -1024,13 +1114,10 @@ pub fn convert_get_type_constructor_error( hint, }, - UnknownTypeConstructorError::Module { - name, - imported_modules, - } => Error::UnknownModule { - location: *location, + UnknownTypeConstructorError::Module { name, suggestions } => Error::UnknownModule { + location: module_location.unwrap_or(*location), name, - imported_modules, + suggestions, }, UnknownTypeConstructorError::ModuleType { @@ -1057,7 +1144,7 @@ pub enum MatchFunTypeError { return_type: Arc, }, NotFn { - typ: Arc, + type_: Arc, }, } @@ -1080,9 +1167,9 @@ pub fn convert_not_fun_error( given, }, - (CallKind::Function, MatchFunTypeError::NotFn { typ }) => Error::NotFn { + (CallKind::Function, MatchFunTypeError::NotFn { type_ }) => Error::NotFn { location: fn_location, - typ, + type_, }, ( @@ -1096,10 +1183,10 @@ pub fn convert_not_fun_error( given, }, - (CallKind::Use { call_location, .. }, MatchFunTypeError::NotFn { typ }) => { + (CallKind::Use { call_location, .. }, MatchFunTypeError::NotFn { type_ }) => { Error::NotFnInUse { location: call_location, - typ, + type_, } } } diff --git a/compiler-core/src/type_/expression.rs b/compiler-core/src/type_/expression.rs index f66a94aa7..0c2198787 100644 --- a/compiler-core/src/type_/expression.rs +++ b/compiler-core/src/type_/expression.rs @@ -13,6 +13,7 @@ use crate::{ build::Target, exhaustiveness, }; +use hexpm::version::Version; use id_arena::Arena; use im::hashmap; use itertools::Itertools; @@ -210,6 +211,9 @@ pub enum ArgumentKind { pub(crate) struct ExprTyper<'a, 'b> { pub(crate) environment: &'a mut Environment<'b>, + /// The minimum Gleam version required to compile the typed expression. + pub minimum_required_version: Version, + // This is set to true if the previous expression that has been typed is // determined to always panic. // For example when typing a literal `panic`, this flag will be set to true. @@ -261,6 +265,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { environment, implementations, current_function_definition: definition, + minimum_required_version: Version::new(0, 1, 0), problems, } } @@ -434,7 +439,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { self.problems.warning(Warning::Todo { kind, location, - typ: type_.clone(), + type_: type_.clone(), }); let message = message @@ -499,7 +504,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { TypedExpr::String { location, value, - typ: string(), + type_: string(), } } @@ -507,7 +512,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { TypedExpr::Int { location, value, - typ: int(), + type_: int(), } } @@ -515,7 +520,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { TypedExpr::Float { location, value, - typ: float(), + type_: float(), } } @@ -560,9 +565,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> { // Helper to push a new error to the errors list and return an invalid expression. fn error_expr_with_rigid_names(&mut self, location: SrcSpan, error: Error) -> TypedExpr { self.error_with_rigid_names(error); + self.error_expr(location) + } + + // Helper to create a new error expr. + fn error_expr(&mut self, location: SrcSpan) -> TypedExpr { TypedExpr::Invalid { location, - typ: self.new_unbound_var(), + type_: self.new_unbound_var(), } } @@ -764,7 +774,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let (args, body) = self.do_infer_fn(args, expected_args, body, &return_annotation)?; let args_types = args.iter().map(|a| a.type_.clone()).collect(); - let typ = fn_(args_types, body.last().type_()); + let type_ = fn_(args_types, body.last().type_()); // Defining an anonymous function never panics. self.already_warned_for_unreachable_code = already_warned_for_unreachable_code; @@ -772,7 +782,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok(TypedExpr::Fn { location, - typ, + type_, is_capture, args, body, @@ -791,7 +801,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { location, .. } = arg; - let typ = annotation + let type_ = annotation .clone() .map(|t| self.type_from_ast(&t)) .unwrap_or_else(|| Ok(self.new_unbound_var()))?; @@ -802,14 +812,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> { // function being type checked, resulting in better type errors and the // record field access syntax working. if let Some(expected) = expected { - unify(expected, typ.clone()).map_err(|e| convert_unify_error(e, location))?; + unify(expected, type_.clone()).map_err(|e| convert_unify_error(e, location))?; } Ok(Arg { names, location, annotation, - type_: typ, + type_, }) } @@ -820,7 +830,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { location: SrcSpan, kind: CallKind, ) -> TypedExpr { - let (fun, args, typ) = self.do_infer_call(fun, args, location, kind); + let (fun, args, type_) = self.do_infer_call(fun, args, location, kind); // One common mistake is to think that the syntax for adding a message // to a `todo` or a `panic` exception is to `todo("...")`, but really @@ -850,7 +860,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { TypedExpr::Call { location, - typ, + type_, args, fun: Box::new(fun), } @@ -862,26 +872,26 @@ impl<'a, 'b> ExprTyper<'a, 'b> { tail: Option>, location: SrcSpan, ) -> Result { - let typ = self.new_unbound_var(); + let type_ = self.new_unbound_var(); // Type check each elements let elements = elements .into_iter() .map(|element| { let element = self.infer(element)?; // Ensure they all have the same type - unify(typ.clone(), element.type_()).map_err(|e| { + unify(type_.clone(), element.type_()).map_err(|e| { convert_unify_error(e.list_element_mismatch(), element.location()) })?; Ok(element) }) .try_collect()?; // Type check the ..tail, if there is one - let typ = list(typ); + let type_ = list(type_); let tail = match tail { Some(tail) => { let tail = self.infer(*tail)?; // Ensure the tail has the same type as the preceding elements - unify(typ.clone(), tail.type_()) + unify(type_.clone(), tail.type_()) .map_err(|e| convert_unify_error(e.list_tail_mismatch(), tail.location()))?; Some(Box::new(tail)) } @@ -889,7 +899,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { }; Ok(TypedExpr::List { location, - typ, + type_, elements, tail, }) @@ -901,11 +911,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> { location: SrcSpan, ) -> Result { let elems: Vec<_> = elems.into_iter().map(|e| self.infer(e)).try_collect()?; - let typ = tuple(elems.iter().map(HasType::type_).collect()); + let type_ = tuple(elems.iter().map(HasType::type_).collect()); Ok(TypedExpr::Tuple { location, elems, - typ, + type_, }) } @@ -999,7 +1009,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { self.problems.error(module_access_err); TypedExpr::Invalid { location: label_location, - typ: self.new_unbound_var(), + type_: self.new_unbound_var(), } } // In any other case use the record access for the error @@ -1011,14 +1021,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> { // Even if the access is not valid Ok(record) => TypedExpr::RecordAccess { location: label_location, - typ: self.new_unbound_var(), + type_: self.new_unbound_var(), label: "".into(), index: u64::MAX, record: Box::new(record), }, Err(_) => TypedExpr::Invalid { location: label_location, - typ: self.new_unbound_var(), + type_: self.new_unbound_var(), }, } } @@ -1031,10 +1041,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> { index: u64, location: SrcSpan, ) -> Result { + if let UntypedExpr::TupleIndex { .. } = tuple { + self.track_feature_usage(FeatureKind::NestedTupleAccess, location); + } + let tuple = self.infer(tuple)?; match collapse_links(tuple.type_()).as_ref() { Type::Tuple { elems } => { - let typ = elems + let type_ = elems .get(index as usize) .ok_or_else(|| Error::OutOfBoundsTupleIndex { location: SrcSpan { @@ -1049,11 +1063,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> { location, index, tuple: Box::new(tuple), - typ, + type_, }) } - typ if typ.is_unbound() => Err(Error::NotATupleUnbound { + type_ if type_.is_unbound() => Err(Error::NotATupleUnbound { location: tuple.location(), }), @@ -1072,14 +1086,26 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let segments = segments .into_iter() .map(|s| { - self.infer_bit_segment(*s.value, s.options, s.location, |env, expr| env.infer(expr)) + let options = match s.value.as_ref() { + UntypedExpr::String { location, .. } if s.options.is_empty() => { + self.track_feature_usage( + FeatureKind::UnannotatedUtf8StringSegment, + *location, + ); + vec![BitArrayOption::Utf8 { + location: SrcSpan::default(), + }] + } + _ => s.options, + }; + self.infer_bit_segment(*s.value, options, s.location, |env, expr| env.infer(expr)) }) .try_collect()?; Ok(TypedExpr::BitArray { location, segments, - typ: bits(), + type_: bits(), }) } @@ -1091,7 +1117,19 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let segments = segments .into_iter() .map(|s| { - self.infer_bit_segment(*s.value, s.options, s.location, |env, expr| { + let options = match s.value.as_ref() { + Constant::String { location, .. } if s.options.is_empty() => { + self.track_feature_usage( + FeatureKind::UnannotatedUtf8StringSegment, + *location, + ); + vec![BitArrayOption::Utf8 { + location: SrcSpan::default(), + }] + } + _ => s.options, + }; + self.infer_bit_segment(*s.value, options, s.location, |env, expr| { Ok(env.infer_const(&None, expr)) }) }) @@ -1114,9 +1152,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let value = infer(self, value)?; let infer_option = |segment_option: BitArrayOption| { - infer_bit_array_option(segment_option, |value, typ| { + infer_bit_array_option(segment_option, |value, type_| { let typed_value = infer(self, value)?; - unify(typ, typed_value.type_()) + unify(type_, typed_value.type_()) .map_err(|e| convert_unify_error(e, typed_value.location()))?; Ok(typed_value) }) @@ -1124,18 +1162,19 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let options: Vec<_> = options.into_iter().map(infer_option).try_collect()?; - let typ = bit_array::type_options_for_value(&options).map_err(|error| { + let type_ = bit_array::type_options_for_value(&options).map_err(|error| { Error::BitArraySegmentError { error: error.error, location: error.location, } })?; - unify(typ.clone(), value.type_()).map_err(|e| convert_unify_error(e, value.location()))?; + unify(type_.clone(), value.type_()) + .map_err(|e| convert_unify_error(e, value.location()))?; Ok(BitArraySegment { location, - type_: typ, + type_, value: Box::new(value), options, }) @@ -1160,7 +1199,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { return Ok(TypedExpr::BinOp { location, name, - typ: bool(), + type_: bool(), left: Box::new(left), right: Box::new(right), }); @@ -1203,7 +1242,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok(TypedExpr::BinOp { location, name, - typ: output_type, + type_: output_type, left: Box::new(left), right: Box::new(right), }) @@ -1282,15 +1321,21 @@ impl<'a, 'b> ExprTyper<'a, 'b> { // Ensure the pattern matches the type of the value let pattern_location = pattern.location(); - let pattern = - match pattern::PatternTyper::new(self.environment, &self.hydrator, self.problems) - .unify(pattern, value_typ.clone()) - { - Ok(pattern) => pattern, - Err(error) => { - self.error_pattern_with_rigid_names(pattern_location, error, value_typ.clone()) - } - }; + let mut pattern_typer = + pattern::PatternTyper::new(self.environment, &self.hydrator, self.problems); + let unify_result = pattern_typer.unify(pattern, value_typ.clone()); + + let minimum_required_version = pattern_typer.minimum_required_version; + if minimum_required_version > self.minimum_required_version { + self.minimum_required_version = minimum_required_version; + } + + let pattern = match unify_result { + Ok(pattern) => pattern, + Err(error) => { + self.error_pattern_with_rigid_names(pattern_location, error, value_typ.clone()) + } + }; // Check that any type annotation is accurate. if let Some(annotation) = &annotation { @@ -1411,7 +1456,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { TypedExpr::Case { location, - typ: return_type, + type_: return_type, subjects: typed_subjects, clauses: typed_clauses, } @@ -1468,7 +1513,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { None, TypedExpr::Invalid { location: then_location, - typ: self.new_unbound_var(), + type_: self.new_unbound_var(), }, vec![], vec![], @@ -1505,6 +1550,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .push(pattern_typer.infer_alternative_multi_pattern(m, subjects, location)?); } + let minimum_required_version = pattern_typer.minimum_required_version; + if minimum_required_version > self.minimum_required_version { + self.minimum_required_version = minimum_required_version; + } + Ok((typed_pattern, typed_alternatives)) } @@ -1577,7 +1627,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { }) } - typ if typ.is_unbound() => Err(Error::NotATupleUnbound { + type_ if type_.is_unbound() => Err(Error::NotATupleUnbound { location: tuple.location(), }), @@ -1845,6 +1895,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { right, .. } => { + self.track_feature_usage(FeatureKind::ArithmeticInGuards, location); let left = self.infer_clause_guard(*left)?; unify(int(), left.type_()).map_err(|e| convert_unify_error(e, left.location()))?; let right = self.infer_clause_guard(*right)?; @@ -1863,6 +1914,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { right, .. } => { + self.track_feature_usage(FeatureKind::ArithmeticInGuards, location); let left = self.infer_clause_guard(*left)?; unify(float(), left.type_()) .map_err(|e| convert_unify_error(e, left.location()))?; @@ -1882,6 +1934,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { right, .. } => { + self.track_feature_usage(FeatureKind::ArithmeticInGuards, location); let left = self.infer_clause_guard(*left)?; unify(int(), left.type_()).map_err(|e| convert_unify_error(e, left.location()))?; let right = self.infer_clause_guard(*right)?; @@ -1900,6 +1953,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { right, .. } => { + self.track_feature_usage(FeatureKind::ArithmeticInGuards, location); let left = self.infer_clause_guard(*left)?; unify(float(), left.type_()) .map_err(|e| convert_unify_error(e, left.location()))?; @@ -1919,6 +1973,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { right, .. } => { + self.track_feature_usage(FeatureKind::ArithmeticInGuards, location); let left = self.infer_clause_guard(*left)?; unify(int(), left.type_()).map_err(|e| convert_unify_error(e, left.location()))?; let right = self.infer_clause_guard(*right)?; @@ -1937,6 +1992,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { right, .. } => { + self.track_feature_usage(FeatureKind::ArithmeticInGuards, location); let left = self.infer_clause_guard(*left)?; unify(float(), left.type_()) .map_err(|e| convert_unify_error(e, left.location()))?; @@ -1956,6 +2012,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { right, .. } => { + self.track_feature_usage(FeatureKind::ArithmeticInGuards, location); let left = self.infer_clause_guard(*left)?; unify(int(), left.type_()).map_err(|e| convert_unify_error(e, left.location()))?; let right = self.infer_clause_guard(*right)?; @@ -1974,6 +2031,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { right, .. } => { + self.track_feature_usage(FeatureKind::ArithmeticInGuards, location); let left = self.infer_clause_guard(*left)?; unify(float(), left.type_()) .map_err(|e| convert_unify_error(e, left.location()))?; @@ -1993,6 +2051,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { right, .. } => { + self.track_feature_usage(FeatureKind::ArithmeticInGuards, location); let left = self.infer_clause_guard(*left)?; unify(int(), left.type_()).map_err(|e| convert_unify_error(e, left.location()))?; let right = self.infer_clause_guard(*right)?; @@ -2013,10 +2072,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> { fn infer_guard_record_access( &mut self, - container: ClauseGuard, EcoString>, + container: TypedClauseGuard, label: EcoString, location: SrcSpan, - ) -> Result, EcoString>, Error> { + ) -> Result { let container = Box::new(container); let container_type = container.type_(); let (index, label, type_) = self.infer_known_record_access( @@ -2041,13 +2100,13 @@ impl<'a, 'b> ExprTyper<'a, 'b> { label: EcoString, location: SrcSpan, record_access_erorr: Error, - ) -> Result, EcoString>, Error> { + ) -> Result { let module_access = self .infer_module_access(&name, label, &location, location) .and_then(|ma| match ma { TypedExpr::ModuleSelect { location, - typ, + type_, label, module_name, module_alias, @@ -2056,7 +2115,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { ModuleValueConstructor::Constant { literal, .. } => { Ok(ClauseGuard::ModuleSelect { location, - type_: typ, + type_, label, module_name, module_alias, @@ -2095,7 +2154,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .ok_or_else(|| Error::UnknownModule { name: module_alias.clone(), location: *module_location, - imported_modules: self.environment.imported_modules.keys().cloned().collect(), + suggestions: self + .environment + .suggest_modules(module_alias, Imported::Value(label.clone())), })?; let constructor = @@ -2148,7 +2209,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok(TypedExpr::ModuleSelect { label, - typ: Arc::clone(&type_), + type_: Arc::clone(&type_), location: select_location, module_name, module_alias: module_alias.clone(), @@ -2165,14 +2226,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> { ) -> Result { let record = Box::new(record); let record_type = record.type_(); - let (index, label, typ) = + let (index, label, type_) = self.infer_known_record_access(record_type, record.location(), usage, location, label)?; Ok(TypedExpr::RecordAccess { record, label, index, location, - typ, + type_, }) } @@ -2207,7 +2268,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let unknown_field = |fields| Error::UnknownRecordField { usage, - typ: record_type.clone(), + type_: record_type.clone(), location, label: label.clone(), fields, @@ -2235,7 +2296,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let RecordAccessor { index, label, - type_: typ, + type_, } = accessors .accessors .get(&label) @@ -2244,10 +2305,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let accessor_record_type = accessors.type_.clone(); let mut type_vars = hashmap![]; let accessor_record_type = self.instantiate(accessor_record_type, &mut type_vars); - let typ = self.instantiate(typ, &mut type_vars); + let type_ = self.instantiate(type_, &mut type_vars); unify(accessor_record_type, record_type) .map_err(|e| convert_unify_error(e, record_location))?; - Ok((index, label, typ)) + Ok((index, label, type_)) } fn infer_record_update( @@ -2261,8 +2322,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> { TypedExpr::ModuleSelect { module_alias, label, + location, .. - } => (Some(module_alias), label), + } => (Some((module_alias, location)), label), TypedExpr::Var { name, .. } => (None, name), @@ -2275,8 +2337,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let value_constructor = self .environment - .get_value_constructor(module.as_ref(), &name) - .map_err(|e| convert_get_value_constructor_error(e, location))? + .get_value_constructor(module.as_ref().map(|(module, _)| module), &name) + .map_err(|e| { + convert_get_value_constructor_error( + e, + location, + module.as_ref().map(|(_, location)| *location), + ) + })? .clone(); // It must be a record with a field map for us to be able to update it @@ -2369,7 +2437,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok(TypedExpr::RecordUpdate { location, - typ: spread.type_(), + type_: spread.type_(), spread: Box::new(spread), args, }) @@ -2377,27 +2445,18 @@ impl<'a, 'b> ExprTyper<'a, 'b> { fn infer_value_constructor( &mut self, - module: &Option, + module: &Option<(EcoString, SrcSpan)>, name: &EcoString, location: &SrcSpan, ) -> Result { let constructor = match module { // Look in the current scope for a binding with this name None => { - let constructor = - self.environment - .get_variable(name) - .cloned() - .ok_or_else(|| Error::UnknownVariable { - location: *location, - name: name.clone(), - variables: self.environment.local_value_names(), - type_with_name_in_scope: self - .environment - .module_types - .keys() - .any(|typ| typ == name), - })?; + let constructor = self + .environment + .get_variable(name) + .cloned() + .ok_or_else(|| self.report_name_error(name, location))?; // Register the value as seen for detection of unused values self.environment.increment_usage(name); @@ -2406,20 +2465,17 @@ impl<'a, 'b> ExprTyper<'a, 'b> { } // Look in an imported module for a binding with this name - Some(module_name) => { + Some((module_name, module_location)) => { let (_, module) = &self .environment .imported_modules .get(module_name) .ok_or_else(|| Error::UnknownModule { - location: *location, + location: *module_location, name: module_name.clone(), - imported_modules: self + suggestions: self .environment - .imported_modules - .keys() - .cloned() - .collect(), + .suggest_modules(module_name, Imported::Value(name.clone())), })?; module .values @@ -2438,7 +2494,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let ValueConstructor { publicity, variant, - type_: typ, + type_, deprecation, } = constructor; @@ -2454,15 +2510,39 @@ impl<'a, 'b> ExprTyper<'a, 'b> { self.narrow_implementations(*location, &variant)?; // Instantiate generic variables into unbound variables for this usage - let typ = self.instantiate(typ, &mut hashmap![]); + let type_ = self.instantiate(type_, &mut hashmap![]); Ok(ValueConstructor { publicity, deprecation, variant, - type_: typ, + type_, }) } + fn report_name_error(&mut self, name: &EcoString, location: &SrcSpan) -> Error { + // First try to see if this is a module alias: + // `import gleam/io` + // `io.debug(io)` + // Show nice error message for this case. + let module = self.environment.imported_modules.get(name); + match module { + Some(_) => Error::ModuleAliasUsedAsName { + location: *location, + name: name.clone(), + }, + None => Error::UnknownVariable { + location: *location, + name: name.clone(), + variables: self.environment.local_value_names(), + type_with_name_in_scope: self + .environment + .module_types + .keys() + .any(|typ| typ == name), + }, + } + } + // helper for infer_const to get the value of a constant ignoring annotations fn infer_const_value(&mut self, value: UntypedConstant) -> Result { match value { @@ -2499,7 +2579,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .. } if args.is_empty() => { // Register the module as having been used if it was imported - if let Some(ref module) = &module { + if let Some((module, _)) = &module { _ = self.environment.unused_modules.remove(module); _ = self.environment.unused_module_aliases.remove(module); } @@ -2529,7 +2609,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { location, name, args: vec![], - typ: constructor.type_, + type_: constructor.type_, tag, field_map, }) @@ -2544,7 +2624,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .. } => { // Register the module as having been used if it was imported - if let Some(ref module) = &module { + if let Some((module, _)) = &module { _ = self.environment.unused_modules.remove(module); _ = self.environment.unused_module_aliases.remove(module); } @@ -2574,8 +2654,8 @@ impl<'a, 'b> ExprTyper<'a, 'b> { // TODO: resvisit this. It is rather awkward at present how we // have to convert to this other data structure. let fun = match &module { - Some(module_alias) => { - let typ = Arc::clone(&constructor.type_); + Some((module_alias, _)) => { + let type_ = Arc::clone(&constructor.type_); let module_name = self .environment .imported_modules @@ -2589,7 +2669,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { name: name.clone(), field_map: field_map.clone(), arity: args.len() as u16, - type_: Arc::clone(&typ), + type_: Arc::clone(&type_), location: constructor.variant.definition_location(), documentation: None, }; @@ -2598,7 +2678,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { label: name.clone(), module_alias: module_alias.clone(), module_name, - typ, + type_, constructor: module_value_constructor, location, } @@ -2617,7 +2697,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { // Potentially this could be improved later match self .get_field_map(&fun) - .map_err(|e| convert_get_value_constructor_error(e, location))? + .map_err(|e| convert_get_value_constructor_error(e, location, None))? { // The fun has a field map so labelled arguments may be present and need to be reordered. Some(field_map) => field_map.reorder(&mut args, location)?, @@ -2634,7 +2714,13 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let args = args_types .iter_mut() .zip(args) - .map(|(typ, arg): (&mut Arc, _)| { + .map(|(type_, arg): (&mut Arc, _)| { + if arg.uses_label_shorthand() { + self.track_feature_usage( + FeatureKind::LabelShorthandSyntax, + arg.location, + ); + } let CallArg { label, value, @@ -2642,7 +2728,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { implicit, } = arg; let value = self.infer_const(&None, value); - unify(typ.clone(), value.type_()) + unify(type_.clone(), value.type_()) .map_err(|e| convert_unify_error(e, value.location()))?; Ok(CallArg { label, @@ -2658,7 +2744,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { location, name, args, - typ: return_type, + type_: return_type, tag, field_map, }) @@ -2671,7 +2757,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .. } => { // Register the module as having been used if it was imported - if let Some(ref module) = &module { + if let Some((module, _)) = &module { _ = self.environment.unused_modules.remove(module); _ = self.environment.unused_module_aliases.remove(module); } @@ -2686,7 +2772,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { location, module, name, - typ: Arc::clone(&constructor.type_), + type_: Arc::clone(&constructor.type_), constructor: Some(Box::from(constructor)), }), // It cannot be a Record because then this constant would have been @@ -2700,6 +2786,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { left, right, } => { + self.track_feature_usage(FeatureKind::ConstantStringConcatenation, location); let left = self.infer_const(&None, *left); unify(string(), left.type_()).map_err(|e| { e.operator_situation(BinOp::Concatenate) @@ -2740,7 +2827,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { self.problems.error(e); Constant::Invalid { location: loc, - typ: self.new_unbound_var(), + type_: self.new_unbound_var(), } } // Type annotation and inferred value are valid. Ensure they are unifiable. @@ -2752,7 +2839,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { self.problems.error(e); Constant::Invalid { location: loc, - typ: const_ann, + type_: const_ann, } } else { inferred @@ -2764,7 +2851,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { self.problems.error(value_err); Constant::Invalid { location: loc, - typ: const_ann, + type_: const_ann, } } // Type annotation is invalid but the inferred value is ok. Use the inferred type. @@ -2779,7 +2866,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { self.problems.error(value_err); Constant::Invalid { location: loc, - typ: self.new_unbound_var(), + type_: self.new_unbound_var(), } } } @@ -2805,12 +2892,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> { untyped_elements: Vec, location: SrcSpan, ) -> Result { - let typ = self.new_unbound_var(); + let type_ = self.new_unbound_var(); let mut elements = Vec::with_capacity(untyped_elements.len()); for element in untyped_elements { let element = self.infer_const(&None, element); - unify(typ.clone(), element.type_()) + unify(type_.clone(), element.type_()) .map_err(|e| convert_unify_error(e, element.location()))?; elements.push(element); } @@ -2818,7 +2905,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok(Constant::List { elements, location, - typ: list(typ), + type_: list(type_), }) } @@ -2865,6 +2952,22 @@ impl<'a, 'b> ExprTyper<'a, 'b> { FieldAccessUsage::MethodCall, )), + UntypedExpr::Fn { + location, + is_capture, + arguments, + body, + return_annotation, + .. + } if arguments.len() == args.len() => self.infer_fn_with_call_context( + arguments, + &args, + body, + is_capture, + return_annotation, + location, + ), + fun => self.infer(fun), }; @@ -2875,8 +2978,37 @@ impl<'a, 'b> ExprTyper<'a, 'b> { } }; - let (fun, args, typ) = self.do_infer_call_with_known_fun(fun, args, location, kind); - (fun, args, typ) + let (fun, args, type_) = self.do_infer_call_with_known_fun(fun, args, location, kind); + (fun, args, type_) + } + + fn infer_fn_with_call_context( + &mut self, + args: Vec, + call_args: &[CallArg], + body: Vec1, + is_capture: bool, + return_annotation: Option, + location: SrcSpan, + ) -> Result { + let typed_call_args: Vec> = call_args + .iter() + .map(|a| { + match self.infer(a.value.clone()) { + Ok(arg) => arg, + Err(_e) => self.error_expr(location), + } + .type_() + }) + .collect_vec(); + self.infer_fn( + args, + &typed_call_args, + body, + is_capture, + return_annotation, + location, + ) } pub fn do_infer_call_with_known_fun( @@ -2890,7 +3022,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { // Check to see if the function accepts labelled arguments let field_map = self .get_field_map(&fun) - .map_err(|e| convert_get_value_constructor_error(e, location)) + .map_err(|e| convert_get_value_constructor_error(e, location, None)) .and_then(|field_map| { match field_map { // The fun has a field map so labelled arguments may be present and need to be reordered. @@ -3010,7 +3142,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .iter_mut() .zip(args) .enumerate() - .map(|(i, (typ, arg))| { + .map(|(i, (type_, arg))| { + if arg.uses_label_shorthand() { + self.track_feature_usage(FeatureKind::LabelShorthandSyntax, arg.location); + } + let CallArg { label, value, @@ -3044,7 +3180,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { ) } - let value = match self.infer_call_argument(value, typ.clone(), argument_kind) { + let value = match self.infer_call_argument(value, type_.clone(), argument_kind) { Ok(value) => value, Err(e) => self.error_expr_with_rigid_names(location, e), }; @@ -3075,7 +3211,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { label, value: TypedExpr::Invalid { location, - typ: self.new_unbound_var(), + type_: self.new_unbound_var(), }, implicit: None, location, @@ -3096,12 +3232,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> { fn infer_call_argument( &mut self, value: UntypedExpr, - typ: Arc, + type_: Arc, kind: ArgumentKind, ) -> Result { - let typ = collapse_links(typ); + let type_ = collapse_links(type_); - let value = match (&*typ, value) { + let value = match (&*type_, value) { // If the argument is expected to be a function and we are passed a // function literal with the correct number of arguments then we // have special handling of this argument, passing in information @@ -3135,7 +3271,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { (_, value) => self.infer(value), }?; - unify(typ, value.type_()) + unify(type_, value.type_()) .map_err(|e| convert_unify_call_error(e, value.location(), kind))?; Ok(value) } @@ -3237,7 +3373,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { start: body.last().location().end, end: body.last().location().end, }, - typ: body_typer.new_unbound_var(), + type_: body_typer.new_unbound_var(), })) }; } @@ -3271,7 +3407,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let mut compiler = Compiler::new(self.environment, Arena::new()); let mut arena = PatternArena::new(); - let subject_variable = compiler.new_variable(subject.clone()); + let subject_variable = compiler.subject_variable(subject.clone()); let mut rows = Vec::with_capacity(1); @@ -3301,7 +3437,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { &mut self, location: SrcSpan, subject_types: &[Arc], - clauses: &[Clause, EcoString>], + clauses: &[TypedClause], ) -> Result<(), Error> { use exhaustiveness::{Body, Column, Compiler, PatternArena, Row}; @@ -3310,7 +3446,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let subject_variables = subject_types .iter() - .map(|t| compiler.new_variable(t.clone())) + .map(|t| compiler.subject_variable(t.clone())) .collect_vec(); let mut rows = Vec::with_capacity(clauses.iter().map(Clause::pattern_count).sum::()); @@ -3360,6 +3496,34 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok(()) } + + fn track_feature_usage(&mut self, feature_kind: FeatureKind, location: SrcSpan) { + let minimum_required_version = feature_kind.required_version(); + + // Then if the required version is not in the specified version for the + // range we emit a warning highlighting the usage of the feature. + if let Some(gleam_version) = &self.environment.gleam_version { + if let Some(lowest_allowed_version) = gleam_version.lowest_version() { + // There is a version in the specified range that is lower than + // the one required by this feature! This means that the + // specified range is wrong and would allow someone to run a + // compiler that is too old to know of this feature. + if minimum_required_version > lowest_allowed_version { + self.problems + .warning(Warning::FeatureRequiresHigherGleamVersion { + location, + feature_kind, + minimum_required_version: minimum_required_version.clone(), + wrongfully_allowed_version: lowest_allowed_version, + }) + } + } + } + + if minimum_required_version > self.minimum_required_version { + self.minimum_required_version = minimum_required_version; + } + } } fn check_subject_for_redundant_match( @@ -3489,7 +3653,7 @@ struct UseAssignments { /// fn(_use1) { let Box(x) = _use1 } /// // ^^^^^ The function arguments /// ``` - function_arguments: Vec>, + function_arguments: Vec, /// With sugar /// ```gleam diff --git a/compiler-core/src/type_/hydrator.rs b/compiler-core/src/type_/hydrator.rs index be25cdf28..f73f9b398 100644 --- a/compiler-core/src/type_/hydrator.rs +++ b/compiler-core/src/type_/hydrator.rs @@ -120,19 +120,25 @@ impl Hydrator { // Hydrate the type argument AST into types let mut argument_types = Vec::with_capacity(args.len()); for t in args { - let typ = self.type_from_ast(t, environment, problems)?; - argument_types.push((t.location(), typ)); + let type_ = self.type_from_ast(t, environment, problems)?; + argument_types.push((t.location(), type_)); } // Look up the constructor let TypeConstructor { parameters, - typ: return_type, + type_: return_type, deprecation, .. } = environment .get_type_constructor(module, name) - .map_err(|e| convert_get_type_constructor_error(e, location))? + .map_err(|e| { + convert_get_type_constructor_error( + e, + location, + module.as_ref().map(|(_, location)| *location), + ) + })? .clone(); match deprecation { @@ -168,7 +174,7 @@ impl Hydrator { #[allow(clippy::needless_collect)] // Not needless, used for side effects let parameter_types: Vec<_> = parameters .into_iter() - .map(|typ| environment.instantiate(typ, &mut type_vars, self)) + .map(|type_| environment.instantiate(type_, &mut type_vars, self)) .collect(); let return_type = environment.instantiate(return_type, &mut type_vars, self); diff --git a/compiler-core/src/type_/pattern.rs b/compiler-core/src/type_/pattern.rs index 9dddf4934..7d172fc9c 100644 --- a/compiler-core/src/type_/pattern.rs +++ b/compiler-core/src/type_/pattern.rs @@ -1,3 +1,4 @@ +use hexpm::version::Version; use im::hashmap; use itertools::Itertools; @@ -7,7 +8,9 @@ use itertools::Itertools; use super::*; use crate::{ analyse::{name::check_name_case, Inferred}, - ast::{AssignName, ImplicitCallArgOrigin, Layer, UntypedPatternBitArraySegment}, + ast::{ + AssignName, BitArrayOption, ImplicitCallArgOrigin, Layer, UntypedPatternBitArraySegment, + }, }; use std::sync::Arc; @@ -17,6 +20,9 @@ pub struct PatternTyper<'a, 'b> { mode: PatternMode, initial_pattern_vars: HashSet, problems: &'a mut Problems, + + /// The minimum Gleam version required to compile the typed pattern. + pub minimum_required_version: Version, } enum PatternMode { @@ -35,6 +41,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { hydrator, mode: PatternMode::Initial, initial_pattern_vars: HashSet::new(), + minimum_required_version: Version::new(0, 1, 0), problems, } } @@ -42,7 +49,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { fn insert_variable( &mut self, name: &str, - typ: Arc, + type_: Arc, location: SrcSpan, ) -> Result<(), UnifyError> { self.check_name_case(location, &EcoString::from(name), Named::Variable); @@ -69,7 +76,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { // And now insert the variable for use in the code that comes // after the pattern. self.environment - .insert_local_variable(name.into(), location, typ); + .insert_local_variable(name.into(), location, type_); Ok(()) } @@ -79,7 +86,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { Some(initial) if self.initial_pattern_vars.contains(name) => { assigned.push(name.into()); let initial_typ = initial.type_.clone(); - unify(initial_typ, typ) + unify(initial_typ, type_) } // This variable was not defined in the Initial multi-pattern @@ -179,9 +186,21 @@ impl<'a, 'b> PatternTyper<'a, 'b> { .. } = segment; + let options = match value.as_ref() { + Pattern::String { location, .. } if options.is_empty() => { + self.track_feature_usage(FeatureKind::UnannotatedUtf8StringSegment, *location); + vec![BitArrayOption::Utf8 { + location: SrcSpan::default(), + }] + } + _ => options, + }; + let options: Vec<_> = options .into_iter() - .map(|o| crate::analyse::infer_bit_array_option(o, |value, typ| self.unify(value, typ))) + .map(|o| { + crate::analyse::infer_bit_array_option(o, |value, type_| self.unify(value, type_)) + }) .try_collect()?; let segment_type = bit_array::type_options_for_pattern(&options, !is_last_segment) @@ -190,7 +209,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { location: error.location, })?; - let typ = { + let type_ = { match value.deref() { Pattern::Variable { .. } if segment_type == string() => { Err(Error::BitArraySegmentError { @@ -201,13 +220,13 @@ impl<'a, 'b> PatternTyper<'a, 'b> { _ => Ok(segment_type), } }?; - let typed_value = self.unify(*value, typ.clone())?; + let typed_value = self.unify(*value, type_.clone())?; Ok(BitArraySegment { location, value: Box::new(typed_value), options, - type_: typ, + type_, }) } @@ -255,19 +274,19 @@ impl<'a, 'b> PatternTyper<'a, 'b> { .environment .module_types .keys() - .any(|typ| typ == &name), + .any(|type_| type_ == &name), })?; self.environment.increment_usage(&name); - let typ = + let type_ = self.environment .instantiate(vc.type_.clone(), &mut hashmap![], self.hydrator); - unify(int(), typ.clone()).map_err(|e| convert_unify_error(e, location))?; + unify(int(), type_.clone()).map_err(|e| convert_unify_error(e, location))?; Ok(Pattern::VarUsage { name, location, constructor: Some(vc), - type_: typ, + type_, }) } @@ -396,7 +415,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { let elems = elems .into_iter() .zip(type_elems) - .map(|(pattern, typ)| self.unify(pattern, typ.clone())) + .map(|(pattern, type_)| self.unify(pattern, type_.clone())) .try_collect()?; Ok(Pattern::Tuple { elems, location }) } @@ -448,8 +467,14 @@ impl<'a, 'b> PatternTyper<'a, 'b> { let cons = self .environment - .get_value_constructor(module.as_ref(), &name) - .map_err(|e| convert_get_value_constructor_error(e, location))?; + .get_value_constructor(module.as_ref().map(|(module, _)| module), &name) + .map_err(|e| { + convert_get_value_constructor_error( + e, + location, + module.as_ref().map(|(_, location)| *location), + ) + })?; match cons.field_map() { // The fun has a field map so labelled arguments may be present and need to be reordered. @@ -609,14 +634,21 @@ impl<'a, 'b> PatternTyper<'a, 'b> { let pattern_args = pattern_args .into_iter() .zip(args) - .map(|(arg, typ)| { + .map(|(arg, type_)| { + if !arg.is_implicit() && arg.uses_label_shorthand() { + self.track_feature_usage( + FeatureKind::LabelShorthandSyntax, + arg.location, + ); + } + let CallArg { value, location, implicit, label, } = arg; - let value = self.unify(value, typ.clone())?; + let value = self.unify(value, type_.clone())?; Ok(CallArg { value, location, @@ -680,4 +712,32 @@ impl<'a, 'b> PatternTyper<'a, 'b> { self.problems.error(error); } } + + fn track_feature_usage(&mut self, feature_kind: FeatureKind, location: SrcSpan) { + let minimum_required_version = feature_kind.required_version(); + + // Then if the required version is not in the specified version for the + // range we emit a warning highlighting the usage of the feature. + if let Some(gleam_version) = &self.environment.gleam_version { + if let Some(lowest_allowed_version) = gleam_version.lowest_version() { + // There is a version in the specified range that is lower than + // the one required by this feature! This means that the + // specified range is wrong and would allow someone to run a + // compiler that is too old to know of this feature. + if minimum_required_version > lowest_allowed_version { + self.problems + .warning(Warning::FeatureRequiresHigherGleamVersion { + location, + feature_kind, + minimum_required_version: minimum_required_version.clone(), + wrongfully_allowed_version: lowest_allowed_version, + }) + } + } + } + + if minimum_required_version > self.minimum_required_version { + self.minimum_required_version = minimum_required_version; + } + } } diff --git a/compiler-core/src/type_/pipe.rs b/compiler-core/src/type_/pipe.rs index b8ccd1928..7f055e289 100644 --- a/compiler-core/src/type_/pipe.rs +++ b/compiler-core/src/type_/pipe.rs @@ -80,7 +80,6 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { expressions: impl IntoIterator, ) -> Result { let mut finally = None; - let expressions = expressions.into_iter().collect_vec(); for (i, call) in expressions.into_iter().enumerate() { if self.expr_typer.previous_panics { @@ -91,6 +90,21 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { self.warn_if_call_first_argument_is_hole(&call); let call = match call { + func @ UntypedExpr::Fn { location, .. } => { + let (func, args, return_type) = self.expr_typer.do_infer_call( + func.clone(), + vec![self.untyped_left_hand_value_variable_call_argument()], + location, + CallKind::Function, + ); + TypedExpr::Call { + location, + args, + type_: return_type, + fun: Box::new(func), + } + } + // left |> right(..args) UntypedExpr::Call { fun, @@ -101,9 +115,7 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { let fun = self.expr_typer.infer(*fun)?; match fun.type_().fn_types() { // Rewrite as right(..args)(left) - Some((args, return_)) - if args.len() == arguments.len() && return_.fn_arity() == Some(1) => - { + Some((args, _)) if args.len() == arguments.len() => { self.infer_apply_to_call_pipe(fun, arguments, location) } // Rewrite as right(left, ..args) @@ -214,7 +226,7 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { args: Vec>, location: SrcSpan, ) -> TypedExpr { - let (function, args, typ) = self.expr_typer.do_infer_call_with_known_fun( + let (function, args, type_) = self.expr_typer.do_infer_call_with_known_fun( function, args, location, @@ -222,7 +234,7 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { ); let function = TypedExpr::Call { location, - typ, + type_, args, fun: Box::new(function), }; @@ -232,7 +244,7 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { // the function below. If it is not we don't know if the error comes // from incorrect usage of the pipe or if it originates from the // argument expressions. - let (function, args, typ) = self.expr_typer.do_infer_call_with_known_fun( + let (function, args, type_) = self.expr_typer.do_infer_call_with_known_fun( function, args, location, @@ -240,7 +252,7 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { ); TypedExpr::Call { location, - typ, + type_, args, fun: Box::new(function), } @@ -259,7 +271,7 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { // the function below. If it is not we don't know if the error comes // from incorrect usage of the pipe or if it originates from the // argument expressions. - let (fun, args, typ) = self.expr_typer.do_infer_call_with_known_fun( + let (fun, args, type_) = self.expr_typer.do_infer_call_with_known_fun( function, arguments, location, @@ -267,7 +279,7 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { ); TypedExpr::Call { location, - typ, + type_, args, fun: Box::new(fun), } @@ -297,7 +309,7 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { Ok(TypedExpr::Call { location: function.location(), - typ: return_type, + type_: return_type, fun: function, args: vec![self.typed_left_hand_value_variable_call_argument()], }) diff --git a/compiler-core/src/type_/prelude.rs b/compiler-core/src/type_/prelude.rs index 4bed9d518..b67595577 100644 --- a/compiler-core/src/type_/prelude.rs +++ b/compiler-core/src/type_/prelude.rs @@ -1,3 +1,4 @@ +use hexpm::version::Version; use strum::{EnumIter, IntoEnumIterator}; use crate::{ @@ -209,13 +210,13 @@ pub fn build_prelude(ids: &UniqueIdGenerator) -> ModuleInterface { types_value_constructors: HashMap::new(), values: HashMap::new(), accessors: HashMap::new(), - unused_imports: Vec::new(), is_internal: false, warnings: vec![], // prelude doesn't have real src src_path: "".into(), // prelude doesn't have real line numbers line_numbers: LineNumbers::new(""), + minimum_required_version: Version::new(0, 1, 0), }; for t in PreludeType::iter() { @@ -224,7 +225,7 @@ pub fn build_prelude(ids: &UniqueIdGenerator) -> ModuleInterface { let v = TypeConstructor { origin: Default::default(), parameters: vec![], - typ: bits(), + type_: bits(), module: PRELUDE_MODULE_NAME.into(), publicity: Publicity::Public, deprecation: NotDeprecated, @@ -287,7 +288,7 @@ pub fn build_prelude(ids: &UniqueIdGenerator) -> ModuleInterface { TypeConstructor { origin: Default::default(), parameters: vec![], - typ: bool(), + type_: bool(), module: PRELUDE_MODULE_NAME.into(), publicity: Publicity::Public, deprecation: NotDeprecated, @@ -302,7 +303,7 @@ pub fn build_prelude(ids: &UniqueIdGenerator) -> ModuleInterface { TypeConstructor { origin: Default::default(), parameters: vec![], - typ: float(), + type_: float(), module: PRELUDE_MODULE_NAME.into(), publicity: Publicity::Public, deprecation: NotDeprecated, @@ -316,7 +317,7 @@ pub fn build_prelude(ids: &UniqueIdGenerator) -> ModuleInterface { INT.into(), TypeConstructor { parameters: vec![], - typ: int(), + type_: int(), origin: Default::default(), module: PRELUDE_MODULE_NAME.into(), publicity: Publicity::Public, @@ -333,7 +334,7 @@ pub fn build_prelude(ids: &UniqueIdGenerator) -> ModuleInterface { TypeConstructor { origin: Default::default(), parameters: vec![list_parameter.clone()], - typ: list(list_parameter), + type_: list(list_parameter), module: PRELUDE_MODULE_NAME.into(), publicity: Publicity::Public, deprecation: NotDeprecated, @@ -364,7 +365,7 @@ pub fn build_prelude(ids: &UniqueIdGenerator) -> ModuleInterface { TypeConstructor { origin: Default::default(), parameters: vec![], - typ: nil(), + type_: nil(), module: PRELUDE_MODULE_NAME.into(), publicity: Publicity::Public, deprecation: NotDeprecated, @@ -393,7 +394,7 @@ pub fn build_prelude(ids: &UniqueIdGenerator) -> ModuleInterface { TypeConstructor { origin: Default::default(), parameters: vec![result_value.clone(), result_error.clone()], - typ: result(result_value.clone(), result_error.clone()), + type_: result(result_value.clone(), result_error.clone()), module: PRELUDE_MODULE_NAME.into(), publicity: Publicity::Public, deprecation: NotDeprecated, @@ -464,7 +465,7 @@ pub fn build_prelude(ids: &UniqueIdGenerator) -> ModuleInterface { TypeConstructor { origin: Default::default(), parameters: vec![], - typ: string(), + type_: string(), module: PRELUDE_MODULE_NAME.into(), publicity: Publicity::Public, deprecation: NotDeprecated, @@ -479,7 +480,7 @@ pub fn build_prelude(ids: &UniqueIdGenerator) -> ModuleInterface { TypeConstructor { origin: Default::default(), parameters: vec![], - typ: utf_codepoint(), + type_: utf_codepoint(), module: PRELUDE_MODULE_NAME.into(), publicity: Publicity::Public, deprecation: NotDeprecated, diff --git a/compiler-core/src/type_/pretty.rs b/compiler-core/src/type_/pretty.rs index 1116ca0a3..9148abf05 100644 --- a/compiler-core/src/type_/pretty.rs +++ b/compiler-core/src/type_/pretty.rs @@ -35,14 +35,14 @@ impl Printer { /// Render a Type as a well formatted string. /// - pub fn pretty_print(&mut self, typ: &Type, initial_indent: usize) -> String { + pub fn pretty_print(&mut self, type_: &Type, initial_indent: usize) -> String { let mut buffer = String::with_capacity(initial_indent); for _ in 0..initial_indent { buffer.push(' '); } buffer .to_doc() - .append(self.print(typ)) + .append(self.print(type_)) .nest(initial_indent as isize) .to_pretty_string(80) } @@ -50,8 +50,8 @@ impl Printer { // TODO: have this function return a Document that borrows from the Type. // Is this possible? The lifetime would have to go through the Arc> // for TypeVar::Link'd types. - pub fn print<'a>(&mut self, typ: &Type) -> Document<'a> { - match typ { + pub fn print<'a>(&mut self, type_: &Type) -> Document<'a> { + match type_ { Type::Named { name, args, module, .. } => { @@ -81,7 +81,7 @@ impl Printer { .group(), ), - Type::Var { type_: typ, .. } => self.type_var_doc(&typ.borrow()), + Type::Var { type_, .. } => self.type_var_doc(&type_.borrow()), Type::Tuple { elems, .. } => self.args_to_gleam_doc(elems).surround("#(", ")"), } @@ -95,9 +95,9 @@ impl Printer { } } - fn type_var_doc<'a>(&mut self, typ: &TypeVar) -> Document<'a> { - match typ { - TypeVar::Link { type_: ref typ, .. } => self.print(typ), + fn type_var_doc<'a>(&mut self, type_: &TypeVar) -> Document<'a> { + match type_ { + TypeVar::Link { ref type_, .. } => self.print(type_), TypeVar::Unbound { id, .. } | TypeVar::Generic { id, .. } => self.generic_type_var(*id), } } @@ -247,9 +247,9 @@ fn next_letter_test() { #[test] fn pretty_print_test() { macro_rules! assert_string { - ($src:expr, $typ:expr $(,)?) => { + ($src:expr, $type_:expr $(,)?) => { let mut printer = Printer::new(); - assert_eq!($typ.to_string(), printer.pretty_print(&$src, 0),); + assert_eq!($type_.to_string(), printer.pretty_print(&$src, 0),); }; } @@ -455,6 +455,6 @@ fn function_test() { } #[cfg(test)] -fn pretty_print(typ: Arc) -> String { - Printer::new().pretty_print(&typ, 0) +fn pretty_print(type_: Arc) -> String { + Printer::new().pretty_print(&type_, 0) } diff --git a/compiler-core/src/type_/printer.rs b/compiler-core/src/type_/printer.rs index b593b4e09..10463b0bc 100644 --- a/compiler-core/src/type_/printer.rs +++ b/compiler-core/src/type_/printer.rs @@ -148,7 +148,7 @@ impl TypeNames { return NamedTypeNames::Qualified(module, name.as_str()); }; - return NamedTypeNames::Unimported(name.as_str()); + NamedTypeNames::Unimported(name.as_str()) } /// A suitable name of a type variable. @@ -253,8 +253,8 @@ impl<'a> Printer<'a> { self.print(retrn, buffer); } - Type::Var { type_: typ, .. } => match *typ.borrow() { - TypeVar::Link { type_: ref typ, .. } => self.print(typ, buffer), + Type::Var { type_, .. } => match *type_.borrow() { + TypeVar::Link { ref type_, .. } => self.print(type_, buffer), TypeVar::Unbound { id, .. } | TypeVar::Generic { id, .. } => { buffer.push_str(&self.names.type_variable(id)) } @@ -284,7 +284,7 @@ fn test_local_type() { names.named_type_in_scope("mod".into(), "Tiger".into(), "Cat".into()); let mut printer = Printer::new(&mut names); - let typ = Type::Named { + let type_ = Type::Named { name: "Tiger".into(), args: vec![], module: "mod".into(), @@ -292,7 +292,7 @@ fn test_local_type() { package: "".into(), }; - assert_eq!(printer.print_type(&typ), "Cat"); + assert_eq!(printer.print_type(&type_), "Cat"); } #[test] @@ -301,11 +301,11 @@ fn test_generic_type_annotation() { names.type_variable_in_scope(0, "one".into()); let mut printer = Printer::new(&mut names); - let typ = Type::Var { + let type_ = Type::Var { type_: Arc::new(std::cell::RefCell::new(TypeVar::Generic { id: 0 })), }; - assert_eq!(printer.print_type(&typ), "one"); + assert_eq!(printer.print_type(&type_), "one"); } #[test] @@ -313,7 +313,7 @@ fn test_generic_type_var() { let mut names = TypeNames::new("module".into()); let mut printer = Printer::new(&mut names); - let typ = Type::Var { + let type_ = Type::Var { type_: Arc::new(std::cell::RefCell::new(TypeVar::Unbound { id: 0 })), }; @@ -321,7 +321,7 @@ fn test_generic_type_var() { type_: Arc::new(std::cell::RefCell::new(TypeVar::Unbound { id: 1 })), }; - assert_eq!(printer.print_type(&typ), "a"); + assert_eq!(printer.print_type(&type_), "a"); assert_eq!(printer.print_type(&typ2), "b"); } @@ -330,7 +330,7 @@ fn test_tuple_type() { let mut names = TypeNames::new("module".into()); let mut printer = Printer::new(&mut names); - let typ = Type::Tuple { + let type_ = Type::Tuple { elems: vec![ Arc::new(Type::Named { name: "Int".into(), @@ -349,7 +349,7 @@ fn test_tuple_type() { ], }; - assert_eq!(printer.print_type(&typ), "#(gleam.Int, gleam.String)"); + assert_eq!(printer.print_type(&type_), "#(gleam.Int, gleam.String)"); } #[test] @@ -359,7 +359,7 @@ fn test_fn_type() { names.named_type_in_scope("gleam".into(), "Bool".into(), "Bool".into()); let mut printer = Printer::new(&mut names); - let typ = Type::Fn { + let type_ = Type::Fn { args: vec![ Arc::new(Type::Named { name: "Int".into(), @@ -385,7 +385,7 @@ fn test_fn_type() { }), }; - assert_eq!(printer.print_type(&typ), "fn(Int, gleam.String) -> Bool"); + assert_eq!(printer.print_type(&type_), "fn(Int, gleam.String) -> Bool"); } #[test] @@ -394,7 +394,7 @@ fn test_module_alias() { names.imported_module("mod1".into(), "animals".into()); let mut printer = Printer::new(&mut names); - let typ = Type::Named { + let type_ = Type::Named { name: "Cat".into(), args: vec![], module: "mod1".into(), @@ -402,7 +402,7 @@ fn test_module_alias() { package: "".into(), }; - assert_eq!(printer.print_type(&typ), "animals.Cat"); + assert_eq!(printer.print_type(&type_), "animals.Cat"); } #[test] @@ -415,7 +415,7 @@ fn test_type_alias_and_generics() { let mut printer = Printer::new(&mut names); - let typ = Type::Named { + let type_ = Type::Named { name: "Tiger".into(), args: vec![Arc::new(Type::Var { type_: Arc::new(std::cell::RefCell::new(TypeVar::Generic { id: 0 })), @@ -425,7 +425,7 @@ fn test_type_alias_and_generics() { package: "".into(), }; - assert_eq!(printer.print_type(&typ), "Cat(one)"); + assert_eq!(printer.print_type(&type_), "Cat(one)"); } #[test] @@ -438,7 +438,7 @@ fn test_unqualified_import_and_generic() { let mut printer = Printer::new(&mut names); - let typ = Type::Named { + let type_ = Type::Named { name: "Cat".into(), args: vec![Arc::new(Type::Var { type_: Arc::new(std::cell::RefCell::new(TypeVar::Generic { id: 0 })), @@ -448,14 +448,14 @@ fn test_unqualified_import_and_generic() { package: "".into(), }; - assert_eq!(printer.print_type(&typ), "C(one)"); + assert_eq!(printer.print_type(&type_), "C(one)"); } #[test] fn nested_module() { let mut names = TypeNames::new("module".into()); let mut printer = Printer::new(&mut names); - let typ = Type::Named { + let type_ = Type::Named { name: "Cat".into(), args: vec![], module: "one/two/three".into(), @@ -463,7 +463,7 @@ fn nested_module() { package: "".into(), }; - assert_eq!(printer.print_type(&typ), "three.Cat"); + assert_eq!(printer.print_type(&type_), "three.Cat"); } #[test] @@ -478,7 +478,7 @@ fn test_unqualified_import_and_module_alias() { let mut printer = Printer::new(&mut names); - let typ = Type::Named { + let type_ = Type::Named { name: "Cat".into(), args: vec![], module: "mod1".into(), @@ -486,7 +486,7 @@ fn test_unqualified_import_and_module_alias() { package: "".into(), }; - assert_eq!(printer.print_type(&typ), "C"); + assert_eq!(printer.print_type(&type_), "C"); } #[test] @@ -499,7 +499,7 @@ fn test_module_imports() { let mut printer = Printer::new(&mut names); - let typ = Type::Named { + let type_ = Type::Named { name: "Cat".into(), args: vec![], module: "mod".into(), @@ -515,7 +515,7 @@ fn test_module_imports() { package: "".into(), }; - assert_eq!(printer.print_type(&typ), "animals.Cat"); + assert_eq!(printer.print_type(&type_), "animals.Cat"); assert_eq!(printer.print_type(&typ1), "Cat"); } @@ -528,7 +528,7 @@ fn test_multiple_generic_annotations() { let mut printer = Printer::new(&mut names); - let typ = Type::Named { + let type_ = Type::Named { name: "Tiger".into(), args: vec![ Arc::new(Type::Var { @@ -547,7 +547,7 @@ fn test_multiple_generic_annotations() { type_: Arc::new(std::cell::RefCell::new(TypeVar::Generic { id: 2 })), }; - assert_eq!(printer.print_type(&typ), "tigermodule.Tiger(one, two)"); + assert_eq!(printer.print_type(&type_), "tigermodule.Tiger(one, two)"); assert_eq!(printer.print_type(&typ1), "a"); } diff --git a/compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity1.snap b/compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity1.snap new file mode 100644 index 000000000..188deb60d --- /dev/null +++ b/compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity1.snap @@ -0,0 +1,20 @@ +--- +source: compiler-core/src/type_/tests.rs +assertion_line: 2332 +expression: "\npub fn main() {\n let a = 1\n |> fn (x) { #(x, x + 1) }\n |> fn (x, y) { x.0 }\n |> fn (x) { x }\n}\n" +--- +error: Incorrect arity + ┌─ /src/one/two.gleam:5:9 + │ +5 │ |> fn (x, y) { x.0 } + │ ^^^^^^^^^^^^^^^^^ Expected 2 arguments, got 1 + + +error: Type mismatch + ┌─ /src/one/two.gleam:5:21 + │ +5 │ |> fn (x, y) { x.0 } + │ ^ What type is this? + +To index into a tuple we need to know it size, but we don't know anything +about this type yet. Please add some type annotations so we can continue. diff --git a/compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity2.snap b/compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity2.snap new file mode 100644 index 000000000..2da014e73 --- /dev/null +++ b/compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity2.snap @@ -0,0 +1,9 @@ +--- +source: compiler-core/src/type_/tests.rs +expression: "\npub fn main() {\n let a = 1\n |> fn (x) { #(x, x + 1) }\n |> fn (x) { x.0 }\n |> fn (x, y) { x }\n}\n" +--- +error: Incorrect arity + ┌─ /src/one/two.gleam:6:9 + │ +6 │ |> fn (x, y) { x } + │ ^^^^^^^^^^^^^^^ Expected 2 arguments, got 1 diff --git a/compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity3.snap b/compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity3.snap new file mode 100644 index 000000000..185974691 --- /dev/null +++ b/compiler-core/src/type_/snapshots/glistix_core__type___tests__pipe_with_annonymous_unannotated_functions_wrong_arity3.snap @@ -0,0 +1,18 @@ +--- +source: compiler-core/src/type_/tests.rs +expression: "\npub fn main() {\n let a = 1\n |> fn (x) { #(x, x + 1) }\n |> fn (x) { x.0 }\n |> fn () { x }\n}\n" +--- +error: Incorrect arity + ┌─ /src/one/two.gleam:6:9 + │ +6 │ |> fn () { x } + │ ^^^^^^^^^^^ Expected no arguments, got 1 + + +error: Unknown variable + ┌─ /src/one/two.gleam:6:17 + │ +6 │ |> fn () { x } + │ ^ + +The name `x` is not in scope here. diff --git a/compiler-core/src/type_/tests.rs b/compiler-core/src/type_/tests.rs index 10e809d39..7a6f1ad75 100644 --- a/compiler-core/src/type_/tests.rs +++ b/compiler-core/src/type_/tests.rs @@ -11,11 +11,13 @@ use crate::{ }; use ecow::EcoString; use itertools::Itertools; -use std::sync::Arc; +use pubgrub::range::Range; +use std::rc::Rc; use vec1::Vec1; use camino::Utf8PathBuf; +mod accessors; mod assert; mod assignments; mod conditional_compilation; @@ -31,13 +33,14 @@ mod pretty; mod target_implementations; mod type_alias; mod use_; +mod version_inference; mod warnings; #[macro_export] macro_rules! assert_infer { - ($src:expr, $typ:expr $(,)?) => { + ($src:expr, $type_:expr $(,)?) => { let t = $crate::type_::tests::infer($src); - assert_eq!(($src, t), ($src, $typ.to_string()),); + assert_eq!(($src, t), ($src, $type_.to_string()),); }; } @@ -172,14 +175,30 @@ macro_rules! assert_with_module_error { }; } -fn get_warnings(src: &str, deps: Vec>) -> Vec { +fn get_warnings( + src: &str, + deps: Vec>, + gleam_version: Option>, +) -> Vec { let warnings = VectorWarningEmitterIO::default(); - _ = compile_module("test_module", src, Some(Arc::new(warnings.clone())), deps).unwrap(); + _ = compile_module_with_opts( + "test_module", + src, + Some(Rc::new(warnings.clone())), + deps, + Target::Erlang, + TargetSupport::NotEnforced, + gleam_version, + ); warnings.take().into_iter().collect_vec() } -fn get_printed_warnings(src: &str, deps: Vec>) -> String { - print_warnings(get_warnings(src, deps)) +fn get_printed_warnings( + src: &str, + deps: Vec>, + gleam_version: Option>, +) -> String { + print_warnings(get_warnings(src, deps, gleam_version)) } fn print_warnings(warnings: Vec) -> String { @@ -193,14 +212,13 @@ fn print_warnings(warnings: Vec) -> String { #[macro_export] macro_rules! assert_warnings_with_imports { ($(($name:literal, $module_src:literal)),+; $src:literal,) => { - let warnings = $crate::type_::tests::get_warnings( + let output = $crate::type_::tests::get_printed_warnings( $src, vec![ $(("thepackage", $name, $module_src)),* ], + None ); - assert!(!warnings.is_empty()); - let output = $crate::type_::tests::print_warnings(warnings); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }; } @@ -208,7 +226,7 @@ macro_rules! assert_warnings_with_imports { #[macro_export] macro_rules! assert_warning { ($src:expr) => { - let output = $crate::type_::tests::get_printed_warnings($src, vec![]); + let output = $crate::type_::tests::get_printed_warnings($src, vec![], None); assert!(!output.is_empty()); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }; @@ -216,7 +234,8 @@ macro_rules! assert_warning { ($(($name:expr, $module_src:literal)),+, $src:expr) => { let output = $crate::type_::tests::get_printed_warnings( $src, - vec![$(("thepackage", $name, $module_src)),*] + vec![$(("thepackage", $name, $module_src)),*], + None ); assert!(!output.is_empty()); insta::assert_snapshot!(insta::internals::AutoName, output, $src); @@ -225,23 +244,34 @@ macro_rules! assert_warning { ($(($package:expr, $name:expr, $module_src:literal)),+, $src:expr) => { let output = $crate::type_::tests::get_printed_warnings( $src, - vec![$(($package, $name, $module_src)),*] + vec![$(($package, $name, $module_src)),*], + None ); assert!(!output.is_empty()); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }; } +#[macro_export] +macro_rules! assert_warnings_with_gleam_version { + ($gleam_version:expr, $src:expr$(,)?) => { + let output = $crate::type_::tests::get_printed_warnings($src, vec![], Some($gleam_version)); + assert!(!output.is_empty()); + insta::assert_snapshot!(insta::internals::AutoName, output, $src); + }; +} + #[macro_export] macro_rules! assert_no_warnings { ($src:expr $(,)?) => { - let warnings = $crate::type_::tests::get_warnings($src, vec![]); + let warnings = $crate::type_::tests::get_warnings($src, vec![], None); assert_eq!(warnings, vec![]); }; ($(($package:expr, $name:expr, $module_src:literal)),+, $src:expr $(,)?) => { let warnings = $crate::type_::tests::get_warnings( $src, vec![$(($package, $name, $module_src)),*], + None, ); assert_eq!(warnings, vec![]); }; @@ -263,6 +293,7 @@ fn compile_statement_sequence( &mut Environment::new( ids, "thepackage".into(), + None, "themodule".into(), Target::Erlang, &modules, @@ -321,6 +352,7 @@ pub fn infer_module_with_target( dep, target, TargetSupport::NotEnforced, + None, ) .expect("should successfully infer"); ast.type_info @@ -338,7 +370,7 @@ pub fn infer_module_with_target( pub fn compile_module( module_name: &str, src: &str, - warnings: Option>, + warnings: Option>, dep: Vec>, ) -> Result> { compile_module_with_opts( @@ -348,23 +380,24 @@ pub fn compile_module( dep, Target::Erlang, TargetSupport::NotEnforced, + None, ) } pub fn compile_module_with_opts( module_name: &str, src: &str, - warnings: Option>, + warnings: Option>, dep: Vec>, target: Target, target_support: TargetSupport, + gleam_version: Option>, ) -> Result> { let ids = UniqueIdGenerator::new(); let mut modules = im::HashMap::new(); - let emitter = WarningEmitter::new( - warnings.unwrap_or_else(|| Arc::new(VectorWarningEmitterIO::default())), - ); + let emitter = + WarningEmitter::new(warnings.unwrap_or_else(|| Rc::new(VectorWarningEmitterIO::default()))); // DUPE: preludeinsertion // TODO: Currently we do this here and also in the tests. It would be better @@ -407,6 +440,7 @@ pub fn compile_module_with_opts( ast.name = module_name.into(); let mut config = PackageConfig::default(); config.name = "thepackage".into(); + config.gleam_version = gleam_version; let warnings = TypeWarningEmitter::new("/src/warning/wrn.gleam".into(), src.into(), emitter); let inference_result = crate::analyse::ModuleAnalyzerConstructor::<()> { @@ -444,6 +478,7 @@ pub fn module_error_with_target( deps, target, TargetSupport::NotEnforced, + None, ) .expect_err("should infer an error"); let error = Error::Type { @@ -470,6 +505,7 @@ pub fn internal_module_error_with_target( deps, target, TargetSupport::NotEnforced, + None, ) .expect_err("should infer an error"); let error = Error::Type { @@ -716,9 +752,9 @@ fn infer_module_type_retention_test() { ]), values: HashMap::new(), accessors: HashMap::new(), - unused_imports: Vec::new(), line_numbers: LineNumbers::new(""), src_path: "".into(), + minimum_required_version: Version::new(0, 1, 0), } ); } @@ -2228,6 +2264,9 @@ fn assert_suitable_main_function_wrong_arity() { documentation: None, location: Default::default(), module: "module".into(), + external_erlang: None, + external_javascript: None, + external_nix: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -2255,6 +2294,9 @@ fn assert_suitable_main_function_ok() { documentation: None, location: Default::default(), module: "module".into(), + external_erlang: None, + external_javascript: None, + external_nix: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -2282,6 +2324,9 @@ fn assert_suitable_main_function_erlang_not_supported() { documentation: None, location: Default::default(), module: "module".into(), + external_erlang: Some(("wibble".into(), "wobble".into())), + external_javascript: Some(("wobble".into(), "wibble".into())), + external_nix: None, implementations: Implementations { gleam: false, uses_erlang_externals: true, @@ -2309,6 +2354,9 @@ fn assert_suitable_main_function_javascript_not_supported() { documentation: None, location: Default::default(), module: "module".into(), + external_erlang: Some(("wibble".into(), "wobble".into())), + external_javascript: Some(("wobble".into(), "wibble".into())), + external_nix: None, implementations: Implementations { gleam: false, uses_erlang_externals: true, @@ -2322,3 +2370,100 @@ fn assert_suitable_main_function_javascript_not_supported() { }; assert!(assert_suitable_main_function(&value, &"module".into(), Target::JavaScript).is_err(),); } + +#[test] +fn pipe_with_annonymous_unannotated_functions() { + assert_module_infer!( + r#" +pub fn main() { + let a = 1 + |> fn (x) { #(x, x + 1) } + |> fn (x) { x.0 } + |> fn (x) { x } +} +"#, + vec![("main", "fn() -> Int")] + ); +} + +#[test] +fn pipe_with_annonymous_unannotated_functions_wrong_arity1() { + assert_module_error!( + r#" +pub fn main() { + let a = 1 + |> fn (x) { #(x, x + 1) } + |> fn (x, y) { x.0 } + |> fn (x) { x } +} +"# + ); +} + +#[test] +fn pipe_with_annonymous_unannotated_functions_wrong_arity2() { + assert_module_error!( + r#" +pub fn main() { + let a = 1 + |> fn (x) { #(x, x + 1) } + |> fn (x) { x.0 } + |> fn (x, y) { x } +} +"# + ); +} + +#[test] +fn pipe_with_annonymous_unannotated_functions_wrong_arity3() { + assert_module_error!( + r#" +pub fn main() { + let a = 1 + |> fn (x) { #(x, x + 1) } + |> fn (x) { x.0 } + |> fn () { x } +} +"# + ); +} + +#[test] +fn pipe_with_annonymous_mixed_functions() { + assert_module_infer!( + r#" +pub fn main() { + let a = "abc" + |> fn (x) { #(x, x <> "d") } + |> fn (x) { x.0 } + |> fn (x: String) { x } +} +"#, + vec![("main", "fn() -> String")] + ); +} + +#[test] +fn pipe_with_annonymous_functions_using_structs() { + // https://github.com/gleam-lang/gleam/issues/2504 + assert_module_infer!( + r#" +type Date { + Date(day: Day) +} +type Day { + Day(year: Int) +} +fn now() -> Date { + Date(Day(2024)) +} +fn get_day(date: Date) -> Day { + date.day +} +pub fn main() { + now() |> get_day() |> fn (it) { it.year } +} +"#, + vec![("main", "fn() -> Int")] + ); +} diff --git a/compiler-core/src/type_/tests/accessors.rs b/compiler-core/src/type_/tests/accessors.rs new file mode 100644 index 000000000..b1a254892 --- /dev/null +++ b/compiler-core/src/type_/tests/accessors.rs @@ -0,0 +1,26 @@ +use crate::assert_infer_with_module; + +#[test] +fn bug_3629() { + assert_infer_with_module!( + ("imported", "pub type Wibble"), + r#" +import imported + +pub type Exp { + One(field: imported.Wibble) + Two(field: imported.Wibble) +} + +pub fn main() { + let exp = One(todo) + exp.field +} + "#, + vec![ + ("One", "fn(Wibble) -> Exp"), + ("Two", "fn(Wibble) -> Exp"), + ("main", "fn() -> Wibble") + ], + ); +} diff --git a/compiler-core/src/type_/tests/errors.rs b/compiler-core/src/type_/tests/errors.rs index 0ea51a9ad..780140a76 100644 --- a/compiler-core/src/type_/tests/errors.rs +++ b/compiler-core/src/type_/tests/errors.rs @@ -2172,3 +2172,84 @@ pub fn main() { " ); } + +#[test] +fn no_crash_on_duplicate_definition() { + // This previous caused the compiler to crash + assert_module_error!( + " +pub type Wibble { + Wobble + Wobble +} + +pub fn main() { + let wibble = Wobble + case wibble { + Wobble -> Nil + } +} +" + ); +} + +#[test] +fn no_crash_on_duplicate_definition2() { + // This also caused a compiler crash, separate to the above test + assert_module_error!( + " +pub type Wibble { + Wibble + Wobble + Wobble + Wubble +} + +pub fn main() { + let wibble = Wobble + case wibble { + Wibble -> Nil + Wobble -> Nil + Wubble -> Nil + } +} +" + ); +} + +#[test] +fn unknown_module_suggest_import() { + assert_with_module_error!( + ("utils", "pub fn helpful() {}"), + " +pub fn main() { + utils.helpful() +} +", + ); +} + +#[test] +fn unknown_module_suggest_typo_for_imported_module() { + assert_with_module_error!( + ("wibble", "pub fn wobble() {}"), + " +import wibble +pub fn main() { + wible.wobble() +} +", + ); +} + +#[test] +fn unknown_module_suggest_typo_for_unimported_module() { + assert_with_module_error!( + ("wibble/wobble", "pub fn wubble() {}"), + " +pub fn main() { + woble.wubble() +} +", + ); +} diff --git a/compiler-core/src/type_/tests/exhaustiveness.rs b/compiler-core/src/type_/tests/exhaustiveness.rs index ab4445688..b36f28b7b 100644 --- a/compiler-core/src/type_/tests/exhaustiveness.rs +++ b/compiler-core/src/type_/tests/exhaustiveness.rs @@ -1,4 +1,6 @@ -use crate::{assert_module_error, assert_no_warnings, assert_warning}; +use crate::{ + assert_error, assert_module_error, assert_no_warnings, assert_warning, assert_with_module_error, +}; #[test] fn whatever() { @@ -986,3 +988,289 @@ pub fn main(wibble) { " ); } + +#[test] +fn case_error_prints_module_names() { + assert_with_module_error!( + ("wibble", "pub type Wibble { Wibble Wobble }"), + " +import wibble +pub type Things { Thing1 Thing2(Int) } +pub fn main() { + let wobble_thing = #(wibble.Wobble, Thing2(23)) + case wobble_thing { + #(wibble.Wibble, Thing1) -> Nil + } +} +", + ); +} + +#[test] +fn case_error_prints_module_alias() { + assert_with_module_error!( + ("wibble", "pub type Wibble { Wibble Wobble }"), + " +import wibble as wobble +pub fn main() { + case wobble.Wobble { + wobble.Wibble -> Nil + } +} +", + ); +} + +#[test] +fn case_error_prints_unqualified_value() { + assert_with_module_error!( + ("wibble", "pub type Wibble { Wibble Wobble }"), + " +import wibble.{Wibble, Wobble} +pub fn main() { + case Wobble { + Wibble -> Nil + } +} +", + ); +} + +#[test] +fn case_error_prints_aliased_unqualified_value() { + assert_with_module_error!( + ("wibble", "pub type Wibble { Wibble Wobble }"), + " +import wibble.{Wibble, Wobble as Wubble} +pub fn main() { + case Wibble { + Wibble -> Nil + } +} +", + ); +} + +#[test] +fn case_error_prints_prelude_module_unqualified() { + assert_module_error!( + " +pub fn main() { + let result = Ok(Nil) + case result { + Ok(Nil) -> Nil + } +} +" + ); +} + +#[test] +fn case_error_prints_prelude_module_when_shadowed() { + assert_module_error!( + " +import gleam +type MyResult { Ok Error } +pub fn main() { + let res = gleam.Ok(10) + case res { + gleam.Ok(n) -> Nil + } +} +" + ); +} + +#[test] +fn case_error_prints_module_when_shadowed() { + assert_with_module_error!( + ("mod", "pub type Wibble { Wibble Wobble }"), + " +import mod.{Wibble} +type Wibble { Wibble Wobble } +pub fn main() { + let wibble = mod.Wibble + case wibble { + mod.Wobble -> Nil + } +} +" + ); +} + +#[test] +fn case_error_prints_module_when_aliased_and_shadowed() { + assert_with_module_error!( + ("mod", "pub type Wibble { Wibble Wobble }"), + " +import mod.{Wibble as Wobble} +type Wibble { Wobble Wubble } +pub fn main() { + let wibble = mod.Wibble + case wibble { + mod.Wobble -> Nil + } +} +" + ); +} + +#[test] +fn case_error_prints_unqualifed_when_aliased() { + assert_with_module_error!( + ("mod", "pub type Wibble { Wibble Wobble }"), + " +import mod.{Wibble as Wobble} +type Wibble { Wibble Wubble } +pub fn main() { + let wibble = mod.Wibble + case wibble { + mod.Wobble -> Nil + } +} +" + ); +} + +// The following few tests all verify that the compiler provides useful errors +// when there are no case arms, instead of just suggesting `_` as it did previously. +#[test] +fn empty_case_of_bool() { + assert_error!( + " +let b = True +case b {} +" + ); +} + +#[test] +fn empty_case_of_custom_type() { + assert_module_error!( + " +type Wibble { Wibble Wobble Wubble } +pub fn main() { + let wibble = Wobble + case wibble {} +} +" + ); +} + +#[test] +fn empty_case_of_list() { + assert_error!( + " +let list = [] +case list {} +" + ); +} + +#[test] +fn empty_case_of_int() { + assert_error!( + " +let num = 24 +case num {} +" + ); +} + +#[test] +fn empty_case_of_float() { + assert_error!( + " +let age = 10.6 +case age {} +" + ); +} + +#[test] +fn empty_case_of_string() { + assert_error!( + r#" +let name = "John Doe" +case name {} +"# + ); +} + +#[test] +fn empty_case_of_multi_pattern() { + assert_error!( + " +let a = Ok(1) +let b = True +case a, b {} +" + ); +} + +#[test] +fn inexhaustive_multi_pattern() { + assert_error!( + " +let a = Ok(1) +let b = True +case a, b { + Error(_), _ -> Nil +} +" + ); +} + +#[test] +fn inexhaustive_multi_pattern2() { + assert_error!( + " +let a = Ok(1) +let b = True +case a, b { + Ok(1), True -> Nil +} +" + ); +} + +#[test] +fn inexhaustive_multi_pattern3() { + assert_error!( + " +let a = Ok(1) +let b = True +case a, b { + _, False -> Nil +} +" + ); +} + +#[test] +fn inexhaustive_multi_pattern4() { + assert_error!( + " +let a = 12 +let b = 3.14 +let c = False +case a, b, c { + 1, 2.0, True -> Nil +} +" + ); +} + +#[test] +fn inexhaustive_multi_pattern5() { + assert_error!( + " +let a = 12 +let b = 3.14 +let c = False +case a, b, c { + 12, _, False -> Nil +} +" + ); +} diff --git a/compiler-core/src/type_/tests/externals.rs b/compiler-core/src/type_/tests/externals.rs index 9afdcd226..ad7a14918 100644 --- a/compiler-core/src/type_/tests/externals.rs +++ b/compiler-core/src/type_/tests/externals.rs @@ -1,6 +1,6 @@ use crate::{ - assert_js_module_error, assert_js_module_infer, assert_module_error, assert_module_infer, - assert_with_module_error, + assert_infer_with_module, assert_js_module_error, assert_js_module_infer, assert_module_error, + assert_module_infer, assert_with_module_error, }; // https://github.com/gleam-lang/gleam/issues/2324 @@ -181,7 +181,7 @@ fn javascript_only_constant() { r#"@external(javascript, "one", "two") fn javascript_only() -> Int const constant = javascript_only -pub const javascript_only_constant = constant +pub const javascript_only_constant = constant "# ), "import module @@ -208,3 +208,29 @@ pub fn main() -> Int assert_module_infer!(module, vec![("main", "fn() -> Int")]); assert_js_module_error!(module); } + +#[test] +fn unsupported_target_for_unused_import() { + // If we import a function which doesn't support the current target, + // even if we don't use it, the compiler should error + assert_with_module_error!( + ( + "mod", + r#"@external(javascript, "wibble", "wobble") pub fn wobble()"# + ), + "import mod.{wobble}" + ); +} + +#[test] +fn supported_target_for_imported_value() { + assert_infer_with_module!( + ( + "mod", + r#"@external(erlang, "wibble", "wobble") pub fn wobble() -> Int"# + ), + "import mod.{wobble} +pub const wobble = wobble", + vec![("wobble", "fn() -> Int")], + ); +} diff --git a/compiler-core/src/type_/tests/functions.rs b/compiler-core/src/type_/tests/functions.rs index 7fa53756c..7bac5c081 100644 --- a/compiler-core/src/type_/tests/functions.rs +++ b/compiler-core/src/type_/tests/functions.rs @@ -459,3 +459,116 @@ pub fn main() { "# ); } + +// https://github.com/gleam-lang/gleam/issues/2504 +#[test] +fn provide_arg_type_to_fn_implicit_ok() { + assert_module_infer!( + r#" +pub fn main() { + let z = #(1,2) + fn(x) { x.0 }(z) +} +"#, + vec![("main", "fn() -> Int")] + ); +} + +#[test] +fn provide_arg_type_to_fn_explicit_ok() { + assert_module_infer!( + r#" +pub fn main() { + let z = #(1,2) + fn(x: #(Int, Int)) { x.0 }(z) +} +"#, + vec![("main", "fn() -> Int")] + ); +} + +#[test] +fn provide_arg_type_to_fn_implicit_error() { + assert_module_error!( + r#" +pub fn main() { + let z = #(1,2) + fn(x) { x.2 }(z) +} +"# + ); +} + +#[test] +fn provide_arg_type_to_fn_explicit_error() { + assert_module_error!( + r#" +pub fn main() { + let z = #(1,2) + fn(x: #(Int, Int)) { x.2 }(z) +} +"# + ); +} + +#[test] +fn provide_arg_type_to_fn_arg_infer_error() { + assert_module_error!( + r#" +pub fn main() { + fn(x) { x.2 }(z) +} +"# + ); +} + +#[test] +fn provide_arg_type_to_fn_not_a_tuple() { + assert_module_error!( + r#" +pub fn main() { + let z = "not a tuple" + fn(x) { x.2 }(z) +} +"# + ); +} + +#[test] +fn provide_two_args_type_to_fn() { + assert_module_infer!( + r#" +pub fn main() { + let a = #(1,2) + let b = #(1,2) + fn(x, y) { x.0 + y.1 }(a, b) +} +"#, + vec![("main", "fn() -> Int")] + ); +} + +#[test] +fn provide_one_arg_type_to_two_args_fn() { + assert_module_error!( + r#" +pub fn main() { + let a = #(1,2) + fn(x, y) { x.0 + y.1 }(a) +} +"# + ); +} + +#[test] +fn provide_two_args_type_to_fn_wrong_types() { + assert_module_error!( + r#" +pub fn main() { + let a = 1 + let b = "not an int" + fn(x, y) { x + y }(a, b) +} +"# + ); +} diff --git a/compiler-core/src/type_/tests/imports.rs b/compiler-core/src/type_/tests/imports.rs index 5ee96b5d7..c7c104966 100644 --- a/compiler-core/src/type_/tests/imports.rs +++ b/compiler-core/src/type_/tests/imports.rs @@ -312,3 +312,17 @@ pub fn main() -> Integer { }" ); } + +#[test] +fn module_alias_used_as_a_name() { + assert_with_module_error!( + ("one/two", ""), + " +import one/two + +pub fn main() { + two +} +" + ); +} diff --git a/compiler-core/src/type_/tests/pipes.rs b/compiler-core/src/type_/tests/pipes.rs index 0abdd1c9f..8446f7d16 100644 --- a/compiler-core/src/type_/tests/pipes.rs +++ b/compiler-core/src/type_/tests/pipes.rs @@ -1,4 +1,4 @@ -use crate::assert_module_infer; +use crate::{assert_module_error, assert_module_infer}; // https://github.com/gleam-lang/gleam/issues/2392 #[test] @@ -41,3 +41,115 @@ pub fn main() { vec![("main", "fn() -> fn(Int) -> Int")] ); } + +#[test] +fn pipe_regression_gh3515() { + // https://github.com/gleam-lang/gleam/issues/3515 + assert_module_infer!( + r#" +fn relu(t) { + fn(theta: String) { + // use t and theta and return a Float + 0.0 + } +} + +pub fn k_relu(k: Int) { + fn(t: Float) { + fn(theta: String) { + case k { + 0 -> t + _ -> { + // following code is OK on gleam 1.3.2, + // but raised error on gleam 1.4.1 + // The key here is that it is not a direct function call, + // but a "var" call, which points to the same function. + let next_layer = theta |> relu(t) |> k_relu(k - 1) + theta |> next_layer + } + } + } + } +}"#, + vec![("k_relu", "fn(Int) -> fn(Float) -> fn(String) -> Float")], + ); +} + +#[test] +fn pipe_callback_var_function1() { + assert_module_infer!( + r#" +pub fn main() { + let f = fn(a) { fn(b) { #(a, b) } } + let x = 1 |> f() +} +"#, + vec![("main", "fn() -> fn(a) -> #(Int, a)")], + ); +} + +#[test] +fn pipe_callback_var_function2() { + assert_module_infer!( + r#" +pub fn main() { + let f = fn(a) { fn(b) { #(a, b) } } + let x = 1 |> f(1) +} +"#, + vec![("main", "fn() -> #(Int, Int)")], + ); +} + +#[test] +fn pipe_callback_correct_arity1() { + assert_module_infer!( + r#" +fn callback(a: Int) { + fn() -> String { + "Called" + } +} + +pub fn main() { + let x = 1 |> callback() +} +"#, + vec![("main", "fn() -> fn() -> String")], + ); +} + +#[test] +fn pipe_callback_correct_arity2() { + assert_module_infer!( + r#" +fn callback(a: Float) { + fn(b: Int) -> String { + "Called" + } +} + +pub fn main() { + let x = 1 |> callback(2.5) +} +"#, + vec![("main", "fn() -> String")], + ); +} + +#[test] +fn pipe_callback_wrong_arity() { + assert_module_error!( + r#" +fn callback(a: Int) { + fn() -> String { + "Called" + } +} + +pub fn main() { + let x = 1 |> callback(2) +} +"# + ); +} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__custom_type_module_constants.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__custom_type_module_constants.snap index 9c02403fe..2501c2eb9 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__custom_type_module_constants.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__custom_type_module_constants.snap @@ -6,6 +6,6 @@ error: Unknown module ┌─ /src/one/two.gleam:2:11 │ 2 │ const x = unknown.X - │ ^^^^^^^^^ + │ ^^^^^^^ No module has been found with the name `unknown`. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__module_arity_error.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__module_arity_error.snap index 2fbb1d94b..98310622a 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__module_arity_error.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__module_arity_error.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/errors.rs +assertion_line: 764 expression: "fn go(x: List(a, b)) -> Int { 1 }" --- error: Incorrect arity @@ -8,5 +9,5 @@ error: Incorrect arity 1 │ fn go(x: List(a, b)) -> Int { 1 } │ ^^^^^^^^^^ Expected 1 argument, got 2 -Functions and constructors have to be called with their expected -number of arguments. +Functions and constructors have to be called with their expected number +of arguments. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__no_crash_on_duplicate_definition.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__no_crash_on_duplicate_definition.snap new file mode 100644 index 000000000..4d71f10e5 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__no_crash_on_duplicate_definition.snap @@ -0,0 +1,14 @@ +--- +source: compiler-core/src/type_/tests/errors.rs +expression: "\ntype Wibble {\n Wobble\n Wobble\n}\n\npub fn main() {\n let wibble = Wobble\n case wibble {\n Wobble -> Nil\n }\n}\n" +--- +error: Duplicate definition + ┌─ /src/one/two.gleam:3:3 + │ +3 │ Wobble + │ ^^^^^^ First defined here +4 │ Wobble + │ ^^^^^^ Redefined here + +`Wobble` has been defined multiple times. +Names in a Gleam module must be unique so one will need to be renamed. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__no_crash_on_duplicate_definition2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__no_crash_on_duplicate_definition2.snap new file mode 100644 index 000000000..d3b838e12 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__no_crash_on_duplicate_definition2.snap @@ -0,0 +1,14 @@ +--- +source: compiler-core/src/type_/tests/errors.rs +expression: "\npub type Wibble {\n Wibble\n Wobble\n Wobble\n Wubble\n}\n\npub fn main() {\n let wibble = Wobble\n case wibble {\n Wibble -> Nil\n Wobble -> Nil\n Wubble -> Nil\n }\n}\n" +--- +error: Duplicate definition + ┌─ /src/one/two.gleam:4:3 + │ +4 │ Wobble + │ ^^^^^^ First defined here +5 │ Wobble + │ ^^^^^^ Redefined here + +`Wobble` has been defined multiple times. +Names in a Gleam module must be unique so one will need to be renamed. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__recursive_var.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__recursive_var.snap index cafea98f0..259515384 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__recursive_var.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__recursive_var.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/errors.rs +assertion_line: 368 expression: "let id = fn(x) { x(x) } 1" --- error: Recursive type @@ -8,7 +9,7 @@ error: Recursive type 1 │ let id = fn(x) { x(x) } 1 │ ^ -I don't know how to work out what type this value has. It seems -to be defined in terms of itself. +I don't know how to work out what type this value has. It seems to be +defined in terms of itself. Hint: Add some type annotations and try again. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__tuple_index_not_a_tuple_unbound.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__tuple_index_not_a_tuple_unbound.snap index 8877ff7f3..f6c869f2b 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__tuple_index_not_a_tuple_unbound.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__tuple_index_not_a_tuple_unbound.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/errors.rs +assertion_line: 569 expression: "fn(a) { a.2 }" --- error: Type mismatch @@ -8,6 +9,5 @@ error: Type mismatch 1 │ fn(a) { a.2 } │ ^ What type is this? -To index into a tuple we need to know it size, but we don't know -anything about this type yet. Please add some type annotations so -we can continue. +To index into a tuple we need to know it size, but we don't know anything +about this type yet. Please add some type annotations so we can continue. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__type_imported_as_value.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__type_imported_as_value.snap index d8f2eb378..a5c954e96 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__type_imported_as_value.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__type_imported_as_value.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/errors.rs expression: "import gleam/wibble.{Wibble}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:1:22 │ 1 │ import gleam/wibble.{Wibble} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_accessed_type.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_accessed_type.snap index daacb5eda..400866f1c 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_accessed_type.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_accessed_type.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/errors.rs +assertion_line: 574 expression: "fn(a) { a.field }" --- error: Unknown type for record access @@ -8,6 +9,6 @@ error: Unknown type for record access 1 │ fn(a) { a.field } │ ^ I don't know what type this is -In order to access a record field we need to know what type it is, -but I can't tell the type here. Try adding type annotations to your -function and try again. +In order to access a record field we need to know what type it is, but I +can't tell the type here. Try adding type annotations to your function and +try again. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_import.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_import.snap new file mode 100644 index 000000000..8c6f697f8 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_import.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/type_/tests/errors.rs +expression: "\npub fn main() {\n utils.helpful()\n}\n" +--- +error: Unknown module + ┌─ /src/one/two.gleam:3:3 + │ +3 │ utils.helpful() + │ ^^^^^ + +No module has been found with the name `utils`. +Hint: Did you mean to import `utils`? diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_typo_for_imported_module.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_typo_for_imported_module.snap new file mode 100644 index 000000000..f77e45bc1 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_typo_for_imported_module.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/type_/tests/errors.rs +expression: "\nimport wibble\npub fn main() {\n wible.wobble()\n}\n" +--- +error: Unknown module + ┌─ /src/one/two.gleam:4:3 + │ +4 │ wible.wobble() + │ ^^^^^ + +No module has been found with the name `wible`. +Hint: Did you mean `wibble`? diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_typo_for_unimported_module.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_typo_for_unimported_module.snap new file mode 100644 index 000000000..0dcc0d576 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__unknown_module_suggest_typo_for_unimported_module.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/type_/tests/errors.rs +expression: "\npub fn main() {\n woble.wubble()\n}\n" +--- +error: Unknown module + ┌─ /src/one/two.gleam:3:3 + │ +3 │ woble.wubble() + │ ^^^^^ + +No module has been found with the name `woble`. +Hint: Did you mean to import `wibble/wobble` and reference `wobble`? diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__update_multi_variant_record.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__update_multi_variant_record.snap index 859be30bd..7f647d314 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__update_multi_variant_record.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__errors__update_multi_variant_record.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/errors.rs +assertion_line: 1987 expression: "\npub type Point {\n Point2(a: Int, b: Int)\n Point3(a: Int, b: Int, c: Int)\n}\n\npub fn main() {\n Point3(..Point2(a: 1, b: 2))\n}" --- error: Unsafe record update @@ -8,9 +9,9 @@ error: Unsafe record update 8 │ Point3(..Point2(a: 1, b: 2)) │ ^^^^^^ I can't tell this is always the right constructor -This type has multiple constructors so it cannot be safely updated. -If this value was one of the other variants then the update would be -produce incorrect results. +This type has multiple constructors so it cannot be safely updated. If +this value was one of the other variants then the update would be produce +incorrect results. -Consider pattern matching on it with a case expression and then -constructing a new record with its values. +Consider pattern matching on it with a case expression and thenconstructing +a new record with its values. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bit_array_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bit_array_1.snap index 25c157e0e..fd3add2d4 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bit_array_1.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bit_array_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 466 expression: "\npub fn main(x) {\n case x {\n <<>> -> 1\n <<1>> -> 1\n <<2>> -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 7 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bit_array_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bit_array_2.snap index a14ddc24d..58d2a24c9 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bit_array_2.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bit_array_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 481 expression: "\npub fn main(x) {\n case x {\n <<>> -> 1\n <<1>> -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -11,8 +12,8 @@ error: Inexhaustive patterns 6 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bool_false.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bool_false.snap index e55b31a7d..1f97e4a7c 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bool_false.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bool_false.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 58 expression: "\npub fn main(x) {\n case x {\n False -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bool_true.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bool_true.snap index 02840eda3..c4e95fb93 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bool_true.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__bool_true.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 45 expression: "\npub fn main(x) {\n case x {\n True -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_aliased_unqualified_value.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_aliased_unqualified_value.snap new file mode 100644 index 000000000..3651023f6 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_aliased_unqualified_value.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 1039 +expression: "\nimport wibble.{Wibble, Wobble as Wubble}\npub fn main() {\n case Wibble {\n Wibble -> Nil\n }\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:4:5 + │ +4 │ ╭ case Wibble { +5 │ │ Wibble -> Nil +6 │ │ } + │ ╰─────^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + Wubble diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_alias.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_alias.snap new file mode 100644 index 000000000..58685db73 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_alias.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 1009 +expression: "\nimport wibble as wobble\npub fn main() {\n case wobble.Wobble {\n wobble.Wibble -> Nil\n }\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:4:5 + │ +4 │ ╭ case wobble.Wobble { +5 │ │ wobble.Wibble -> Nil +6 │ │ } + │ ╰─────^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + wobble.Wobble diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_names.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_names.snap new file mode 100644 index 000000000..5ab591e24 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_names.snap @@ -0,0 +1,20 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 992 +expression: "\nimport wibble\npub type Things { Thing1 Thing2(Int) }\npub fn main() {\n let wobble_thing = #(wibble.Wobble, Thing2(23))\n case wobble_thing {\n #(wibble.Wibble, Thing1) -> Nil\n }\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:6:5 + │ +6 │ ╭ case wobble_thing { +7 │ │ #(wibble.Wibble, Thing1) -> Nil +8 │ │ } + │ ╰─────^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + #(_, Thing2(_)) + #(wibble.Wobble, Thing1) diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_when_aliased_and_shadowed.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_when_aliased_and_shadowed.snap new file mode 100644 index 000000000..0327345db --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_when_aliased_and_shadowed.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 1101 +expression: "\nimport mod.{Wibble as Wobble}\ntype Wibble { Wobble Wubble }\npub fn main() {\n let wibble = mod.Wibble\n case wibble {\n mod.Wobble -> Nil\n }\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:6:3 + │ +6 │ ╭ case wibble { +7 │ │ mod.Wobble -> Nil +8 │ │ } + │ ╰───^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + mod.Wibble diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_when_shadowed.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_when_shadowed.snap new file mode 100644 index 000000000..2c74fd354 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_module_when_shadowed.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 1084 +expression: "\nimport mod.{Wibble}\ntype Wibble { Wibble Wobble }\npub fn main() {\n let wibble = mod.Wibble\n case wibble {\n mod.Wobble -> Nil\n }\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:6:3 + │ +6 │ ╭ case wibble { +7 │ │ mod.Wobble -> Nil +8 │ │ } + │ ╰───^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + mod.Wibble diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_prelude_module_unqualified.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_prelude_module_unqualified.snap new file mode 100644 index 000000000..948e34627 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_prelude_module_unqualified.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 1054 +expression: "\npub fn main() {\n let result = Ok(Nil)\n case result {\n Ok(Nil) -> Nil\n }\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:4:3 + │ +4 │ ╭ case result { +5 │ │ Ok(Nil) -> Nil +6 │ │ } + │ ╰───^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + Error(_) diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_prelude_module_when_shadowed.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_prelude_module_when_shadowed.snap new file mode 100644 index 000000000..aab6d09dd --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_prelude_module_when_shadowed.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 1068 +expression: "\nimport gleam\ntype MyResult { Ok Error }\npub fn main() {\n let res = gleam.Ok(10)\n case res {\n gleam.Ok(n) -> Nil\n }\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:6:3 + │ +6 │ ╭ case res { +7 │ │ gleam.Ok(n) -> Nil +8 │ │ } + │ ╰───^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + gleam.Error(_) diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_unqualifed_when_aliased.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_unqualifed_when_aliased.snap new file mode 100644 index 000000000..9874107b4 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_unqualifed_when_aliased.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 1118 +expression: "\nimport mod.{Wibble as Wobble}\ntype Wibble { Wibble Wubble }\npub fn main() {\n let wibble = mod.Wibble\n case wibble {\n mod.Wobble -> Nil\n }\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:6:3 + │ +6 │ ╭ case wibble { +7 │ │ mod.Wobble -> Nil +8 │ │ } + │ ╰───^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + Wobble diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_unqualified_value.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_unqualified_value.snap new file mode 100644 index 000000000..b96148bef --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__case_error_prints_unqualified_value.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 1024 +expression: "\nimport wibble.{Wibble, Wobble}\npub fn main() {\n case Wobble {\n Wibble -> Nil\n }\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:4:5 + │ +4 │ ╭ case Wobble { +5 │ │ Wibble -> Nil +6 │ │ } + │ ╰─────^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + Wobble diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__custom_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__custom_1.snap index ef6816c00..f3636ee65 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__custom_1.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__custom_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 781 expression: "\npub type Type {\n One\n Two\n}\n\npub fn main(x) {\n case x {\n One -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 10 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__custom_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__custom_2.snap index 0d96e6a65..8c1a69a54 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__custom_2.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__custom_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 799 expression: "\npub type Type {\n One\n Two\n Three(Type)\n}\n\npub fn main(x) {\n case x {\n One -> 1\n Two -> 2\n Three(One) -> 4\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 13 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_2.snap index bb6df813c..546f69c43 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_2.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 651 expression: "\npub type Thing {\n Thing(a: Bool, b: Bool)\n}\n\npub fn main(x) {\n case x {\n Thing(a: True, ..) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 9 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_3.snap index 3d27eca41..41ca902e6 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_3.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 668 expression: "\npub type Thing {\n Thing(a: Bool, b: Bool)\n}\n\npub fn main(x) {\n case x {\n Thing(a: False, ..) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 9 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_4.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_4.snap index bb6df813c..ea068c63c 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_4.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_4.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 685 expression: "\npub type Thing {\n Thing(a: Bool, b: Bool)\n}\n\npub fn main(x) {\n case x {\n Thing(a: True, ..) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 9 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_5.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_5.snap index 3d27eca41..211db8750 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_5.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_5.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 702 expression: "\npub type Thing {\n Thing(a: Bool, b: Bool)\n}\n\npub fn main(x) {\n case x {\n Thing(a: False, ..) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 9 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_6.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_6.snap index 6b17d48ef..8406556cd 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_6.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__discard_6.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 719 expression: "\npub type Thing {\n Thing(a: Bool, b: Bool)\n}\n\npub fn main(x) {\n case x {\n Thing(False, ..) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 9 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_bool.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_bool.snap new file mode 100644 index 000000000..15183ed2b --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_bool.snap @@ -0,0 +1,17 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet b = True\ncase b {}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:3:1 + │ +3 │ case b {} + │ ^^^^^^^^^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + False + True diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_custom_type.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_custom_type.snap new file mode 100644 index 000000000..a71f265c3 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_custom_type.snap @@ -0,0 +1,18 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\ntype Wibble { Wibble Wobble Wubble }\npub fn main() {\n let wibble = Wobble\n case wibble {}\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:5:3 + │ +5 │ case wibble {} + │ ^^^^^^^^^^^^^^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + Wibble + Wobble + Wubble diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_external.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_external.snap index 88625d95f..8f2caf08c 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_external.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_external.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 944 expression: "\npub type Thingy\n\npub fn main(x: Thingy) {\n case x {\n }\n}\n" --- error: Inexhaustive patterns @@ -9,8 +10,8 @@ error: Inexhaustive patterns 6 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_float.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_float.snap new file mode 100644 index 000000000..a213b0c78 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_float.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet age = 10.6\ncase age {}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:3:1 + │ +3 │ case age {} + │ ^^^^^^^^^^^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + _ diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_generic.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_generic.snap index 834819cd6..73dd31dc5 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_generic.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_generic.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 960 expression: "\npub fn main(x: something) {\n case x {\n }\n}\n" --- error: Inexhaustive patterns @@ -9,8 +10,8 @@ error: Inexhaustive patterns 4 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_int.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_int.snap new file mode 100644 index 000000000..73978c53a --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_int.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet num = 24\ncase num {}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:3:1 + │ +3 │ case num {} + │ ^^^^^^^^^^^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + _ diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_list.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_list.snap new file mode 100644 index 000000000..ef7a5c139 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_list.snap @@ -0,0 +1,17 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet list = []\ncase list {}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:3:1 + │ +3 │ case list {} + │ ^^^^^^^^^^^^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + [] + [_, ..] diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_multi_pattern.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_multi_pattern.snap new file mode 100644 index 000000000..83803b7a5 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_multi_pattern.snap @@ -0,0 +1,17 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet a = Ok(1)\nlet b = True\ncase a, b {}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:4:1 + │ +4 │ case a, b {} + │ ^^^^^^^^^^^^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + Error(_), _ + Ok(_), _ diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_string.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_string.snap new file mode 100644 index 000000000..2e7aad5b2 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__empty_case_of_string.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet name = \"John Doe\"\ncase name {}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:3:1 + │ +3 │ case name {} + │ ^^^^^^^^^^^^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + _ diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__float_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__float_1.snap index c8bdfb642..39be1b240 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__float_1.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__float_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 556 expression: "\npub fn main(x) {\n case x {\n 0.0 -> 1\n 1.1 -> 1\n 2.2 -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 7 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__float_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__float_2.snap index 22b8f0518..213037692 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__float_2.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__float_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 571 expression: "\npub fn main(x) {\n case x {\n 0.0 -> 1\n 1.1 -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -11,8 +12,8 @@ error: Inexhaustive patterns 6 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__guard.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__guard.snap index bb47ecdd4..29c67af45 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__guard.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__guard.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 754 expression: "\npub fn main(x, y) {\n case x {\n _ if y -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__guard_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__guard_1.snap index 423c2234c..4ed44c9f1 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__guard_1.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__guard_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 767 expression: "\npub fn main(x, y) {\n case x {\n True if y -> 1\n False -> 2\n }\n}\n" --- error: Inexhaustive patterns @@ -11,8 +12,8 @@ error: Inexhaustive patterns 6 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern.snap new file mode 100644 index 000000000..9170d830c --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern.snap @@ -0,0 +1,18 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet a = Ok(1)\nlet b = True\ncase a, b {\n Error(_), _ -> Nil\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:4:1 + │ +4 │ ╭ case a, b { +5 │ │ Error(_), _ -> Nil +6 │ │ } + │ ╰─^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + Ok(_), _ diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern2.snap new file mode 100644 index 000000000..80199c255 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern2.snap @@ -0,0 +1,20 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet a = Ok(1)\nlet b = True\ncase a, b {\n Ok(1), True -> Nil\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:4:1 + │ +4 │ ╭ case a, b { +5 │ │ Ok(1), True -> Nil +6 │ │ } + │ ╰─^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + Error(_), True + Ok(_), True + _, False diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern3.snap new file mode 100644 index 000000000..dcb8b1c08 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern3.snap @@ -0,0 +1,18 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet a = Ok(1)\nlet b = True\ncase a, b {\n _, False -> Nil\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:4:1 + │ +4 │ ╭ case a, b { +5 │ │ _, False -> Nil +6 │ │ } + │ ╰─^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + _, True diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern4.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern4.snap new file mode 100644 index 000000000..d04d3f889 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern4.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet a = 12\nlet b = 3.14\nlet c = False\ncase a, b, c {\n 1, 2.0, True -> Nil\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:5:1 + │ +5 │ ╭ case a, b, c { +6 │ │ 1, 2.0, True -> Nil +7 │ │ } + │ ╰─^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + _, _, False + _, _, True diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern5.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern5.snap new file mode 100644 index 000000000..4b702c19d --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__inexhaustive_multi_pattern5.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/type_/tests/exhaustiveness.rs +expression: "\nlet a = 12\nlet b = 3.14\nlet c = False\ncase a, b, c {\n 12, _, False -> Nil\n}\n" +--- +error: Inexhaustive patterns + ┌─ /src/one/two.gleam:5:1 + │ +5 │ ╭ case a, b, c { +6 │ │ 12, _, False -> Nil +7 │ │ } + │ ╰─^ + +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. + +The missing patterns are: + + _, _, False + _, _, True diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__int_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__int_1.snap index 285fbef74..8da2a0e79 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__int_1.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__int_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 511 expression: "\npub fn main(x) {\n case x {\n 0 -> 1\n 1 -> 1\n 2 -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 7 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__int_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__int_2.snap index 8d0df012e..d7a310270 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__int_2.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__int_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 526 expression: "\npub fn main(x) {\n case x {\n 0 -> 1\n 1 -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -11,8 +12,8 @@ error: Inexhaustive patterns 6 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__label_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__label_1.snap index ce1395c79..ad4be1704 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__label_1.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__label_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 736 expression: "\npub type Thing {\n Thing(a: Bool, b: Bool)\n}\n\npub fn main(x) {\n case x {\n Thing(a: False, b: True) -> 1\n Thing(b: False, a: True) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -11,8 +12,8 @@ error: Inexhaustive patterns 10 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__let_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__let_1.snap index 732b44a72..51e865bbb 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__let_1.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__let_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 900 expression: "\npub fn main(x) {\n let True = x\n 0\n}\n" --- error: Inexhaustive pattern @@ -8,9 +9,8 @@ error: Inexhaustive pattern 3 │ let True = x │ ^^^^^^^^^^^^ -This assignment uses a pattern that does not match all possible -values. If one of the other values is used then the assignment -will crash. +This assignment uses a pattern that does not match all possible values. If +one of the other values is used then the assignment will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_bool_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_bool_1.snap index 783311fb8..954bed437 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_bool_1.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_bool_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 585 expression: "\npub fn main(x) {\n case x {\n [] -> 1\n [True] -> 2\n [_, _, ..] -> 2\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 7 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_bool_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_bool_2.snap index 117e2b6ae..89c28c029 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_bool_2.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_bool_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 600 expression: "\npub fn main(x) {\n case x {\n [] -> 1\n [True] -> 2\n [_, False] -> 2\n [_, _, _, ..] -> 2\n }\n}\n" --- error: Inexhaustive patterns @@ -13,8 +14,8 @@ error: Inexhaustive patterns 8 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_empty.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_empty.snap index 9fc648761..2aba3a911 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_empty.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_empty.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 295 expression: "\npub fn main(x) {\n case x {\n [] -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_non_empty.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_non_empty.snap index 2f1f96d15..31a5c3470 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_non_empty.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_non_empty.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 308 expression: "\npub fn main(x) {\n case x {\n [_, ..] -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_one.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_one.snap index 98de5bd51..dc245a9c2 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_one.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_one.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 321 expression: "\npub fn main(x) {\n case x {\n [_] -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_one_two.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_one_two.snap index 0cb22f1b8..868e34a08 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_one_two.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_one_two.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 334 expression: "\npub fn main(x) {\n case x {\n [_] -> 1\n [_, _] -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -11,8 +12,8 @@ error: Inexhaustive patterns 6 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_zero_one_two.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_zero_one_two.snap index b49de3d7e..db4135d29 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_zero_one_two.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_zero_one_two.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 348 expression: "\npub fn main(x) {\n case x {\n [] -> 1\n [_] -> 1\n [_, _] -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 7 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_zero_two_any.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_zero_two_any.snap index 44a18b248..e18fd0be4 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_zero_two_any.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__list_zero_two_any.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 379 expression: "\npub fn main(x) {\n case x {\n [] -> 1\n [_, _] -> 1\n [_, _, ..] -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 7 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__nested_type_parameter_usage.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__nested_type_parameter_usage.snap index 3f7db0d75..7fdd975e1 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__nested_type_parameter_usage.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__nested_type_parameter_usage.snap @@ -1,6 +1,7 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs -expression: "\npub type Returned(a) {\n Returned(List(a))\n}\n\nfn foo(user: Returned(#())) -> Int {\n let Returned([#()]) = user\n 1\n}\n" +assertion_line: 926 +expression: "\npub type Returned(a) {\n Returned(List(a))\n}\n\nfn wibble(user: Returned(#())) -> Int {\n let Returned([#()]) = user\n 1\n}\n" --- error: Inexhaustive pattern ┌─ /src/one/two.gleam:7:3 @@ -8,9 +9,8 @@ error: Inexhaustive pattern 7 │ let Returned([#()]) = user │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ -This assignment uses a pattern that does not match all possible -values. If one of the other values is used then the assignment -will crash. +This assignment uses a pattern that does not match all possible values. If +one of the other values is used then the assignment will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__reference_absent_type.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__reference_absent_type.snap index 0585a92c0..af054201d 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__reference_absent_type.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__reference_absent_type.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 974 expression: "\ntype Wibble {\n One(Int)\n Two(Absent)\n}\n\npub fn main(wibble) {\n case wibble {\n One(x) -> x\n }\n}\n" --- error: Unknown type @@ -30,8 +31,8 @@ error: Inexhaustive patterns 10 │ │ } │ ╰─────^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_1.snap index 801cff5a4..c67d061eb 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_1.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 167 expression: "\npub fn main(x) {\n case x {\n Ok(False) -> 1\n Error(True) -> 2\n Error(False) -> 3\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 7 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_2.snap index eca6e5ac8..d86929a95 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_2.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 182 expression: "\npub fn main(x) {\n case x {\n Ok(True) -> 1\n Error(True) -> 2\n Error(False) -> 3\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 7 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_3.snap index 58632d73b..08d66156d 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_3.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 197 expression: "\npub fn main(x) {\n case x {\n Ok(True) -> 1\n Ok(False) -> 2\n Error(False) -> 3\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 7 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_4.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_4.snap index 83d6f29b5..6f0c1bda0 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_4.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_4.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 212 expression: "\npub fn main(x) {\n case x {\n Ok(True) -> 1\n Ok(False) -> 2\n Error(True) -> 3\n }\n}\n" --- error: Inexhaustive patterns @@ -12,8 +13,8 @@ error: Inexhaustive patterns 7 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_5.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_5.snap index c99e73ca0..74d3b0771 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_5.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_5.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 227 expression: "\npub fn main(x) {\n case x {\n Ok(True) -> 1\n Ok(False) -> 2\n }\n}\n" --- error: Inexhaustive patterns @@ -11,8 +12,8 @@ error: Inexhaustive patterns 6 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_6.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_6.snap index 2bdec6602..bfa51c576 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_6.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_6.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 241 expression: "\npub fn main(x) {\n case x {\n Error(True) -> 1\n Error(False) -> 2\n }\n}\n" --- error: Inexhaustive patterns @@ -11,8 +12,8 @@ error: Inexhaustive patterns 6 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_7.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_7.snap index ea6e46fdc..3a39ccdf8 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_7.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_7.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 255 expression: "\npub fn main(x) {\n case x {\n Error(True) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_8.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_8.snap index 0a1349690..1280788ec 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_8.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_bool_8.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 268 expression: "\npub fn main(x) {\n case x {\n Ok(False) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_error.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_error.snap index 3f6a3cef4..e5d96b0ab 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_error.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_error.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 98 expression: "\npub fn main(x) {\n case x {\n Error(_) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_nil_error.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_nil_error.snap index cd2c2f9eb..35148d94c 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_nil_error.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_nil_error.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 138 expression: "\npub fn main(x) {\n case x {\n Error(Nil) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_nil_ok.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_nil_ok.snap index 2c2b85586..4e7130107 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_nil_ok.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_nil_ok.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 125 expression: "\npub fn main(x) {\n case x {\n Ok(Nil) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_ok.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_ok.snap index 019ba785a..211917fae 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_ok.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__result_ok.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 85 expression: "\npub fn main(x) {\n case x {\n Ok(_) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_1.snap index d598d737f..2ddbad9f7 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_1.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_1.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 410 expression: "\npub fn main(x) {\n case x {\n \"\" -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_2.snap index b9f226614..5fce62fae 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_2.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 423 expression: "\npub fn main(x) {\n case x {\n \"a\" -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_3.snap index 08e2745d4..093c11b6a 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_3.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__string_3.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 436 expression: "\npub fn main(x) {\n case x {\n \"a\" -> 1\n \"b\" -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -11,8 +12,8 @@ error: Inexhaustive patterns 6 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__tuple_0.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__tuple_0.snap index 1fe9bdd12..939687b34 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__tuple_0.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__exhaustiveness__tuple_0.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/exhaustiveness.rs +assertion_line: 912 expression: "\npub fn main(x, y) {\n case #(x, y) {\n #(True, _) -> 1\n }\n}\n" --- error: Inexhaustive patterns @@ -10,8 +11,8 @@ error: Inexhaustive patterns 5 │ │ } │ ╰───^ -This case expression does not have a pattern for all possible values. -If it is run on one of the values without a pattern then it will crash. +This case expression does not have a pattern for all possible values. If it +is run on one of the values without a pattern then it will crash. The missing patterns are: diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__externals__unsupported_target_for_unused_import.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__externals__unsupported_target_for_unused_import.snap new file mode 100644 index 000000000..dcaa35cda --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__externals__unsupported_target_for_unused_import.snap @@ -0,0 +1,14 @@ +--- +source: compiler-core/src/type_/tests/externals.rs +expression: "import mod.{wobble}" +--- +error: Unsupported target + ┌─ /src/one/two.gleam:1:13 + │ +1 │ import mod.{wobble} + │ ^^^^^^ + +This value is not available as it is defined using externals, and there is +no implementation for the Erlang target. + +Hint: Did you mean to build for a different target? diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_arg_infer_error.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_arg_infer_error.snap new file mode 100644 index 000000000..812752814 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_arg_infer_error.snap @@ -0,0 +1,21 @@ +--- +source: compiler-core/src/type_/tests/functions.rs +assertion_line: 516 +expression: "\npub fn main() {\n fn(x) { x.2 }(z)\n}\n" +--- +error: Type mismatch + ┌─ /src/one/two.gleam:3:12 + │ +3 │ fn(x) { x.2 }(z) + │ ^ What type is this? + +To index into a tuple we need to know it size, but we don't know anything +about this type yet. Please add some type annotations so we can continue. + +error: Unknown variable + ┌─ /src/one/two.gleam:3:18 + │ +3 │ fn(x) { x.2 }(z) + │ ^ + +The name `z` is not in scope here. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_explicit_error.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_explicit_error.snap new file mode 100644 index 000000000..5100354cd --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_explicit_error.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/type_/tests/functions.rs +expression: "\npub fn main() {\n let z = #(1,2)\n fn(x: #(Int, Int)) { x.2 }(z)\n}\n" +--- +error: Out of bounds tuple index + ┌─ /src/one/two.gleam:4:26 + │ +4 │ fn(x: #(Int, Int)) { x.2 }(z) + │ ^^ This index is too large + +The index being accessed for this tuple is 2, but this tuple has 2 elements +so the highest valid index is 1. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_implicit_error.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_implicit_error.snap new file mode 100644 index 000000000..8395744de --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_implicit_error.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/type_/tests/functions.rs +expression: "\npub fn main() {\n let z = #(1,2)\n fn(x) { x.2 }(z)\n}\n" +--- +error: Out of bounds tuple index + ┌─ /src/one/two.gleam:4:13 + │ +4 │ fn(x) { x.2 }(z) + │ ^^ This index is too large + +The index being accessed for this tuple is 2, but this tuple has 2 elements +so the highest valid index is 1. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_not_a_tuple.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_not_a_tuple.snap new file mode 100644 index 000000000..8a15c3353 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_arg_type_to_fn_not_a_tuple.snap @@ -0,0 +1,13 @@ +--- +source: compiler-core/src/type_/tests/functions.rs +expression: "\npub fn main() {\n let z = \"not a tuple\"\n fn(x) { x.2 }(z)\n}\n" +--- +error: Type mismatch + ┌─ /src/one/two.gleam:4:12 + │ +4 │ fn(x) { x.2 }(z) + │ ^ This is not a tuple + +To index into this value it needs to be a tuple, however it has this type: + + String diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_one_arg_type_to_two_args_fn.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_one_arg_type_to_two_args_fn.snap new file mode 100644 index 000000000..58f9a3d41 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_one_arg_type_to_two_args_fn.snap @@ -0,0 +1,20 @@ +--- +source: compiler-core/src/type_/tests/functions.rs +assertion_line: 553 +expression: "\npub fn main() {\n let a = #(1,2)\n fn(x, y) { x.0 + y.1 }(a)\n}\n" +--- +error: Incorrect arity + ┌─ /src/one/two.gleam:4:4 + │ +4 │ fn(x, y) { x.0 + y.1 }(a) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ Expected 2 arguments, got 1 + + +error: Type mismatch + ┌─ /src/one/two.gleam:4:15 + │ +4 │ fn(x, y) { x.0 + y.1 }(a) + │ ^ What type is this? + +To index into a tuple we need to know it size, but we don't know anything +about this type yet. Please add some type annotations so we can continue. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_two_args_type_to_fn_wrong_types.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_two_args_type_to_fn_wrong_types.snap new file mode 100644 index 000000000..f90ceb9bf --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__provide_two_args_type_to_fn_wrong_types.snap @@ -0,0 +1,20 @@ +--- +source: compiler-core/src/type_/tests/functions.rs +expression: "\npub fn main() {\n let a = 1\n let b = \"not an int\"\n fn(x, y) { x + y }(a, b)\n}\n" +--- +error: Type mismatch + ┌─ /src/one/two.gleam:5:19 + │ +5 │ fn(x, y) { x + y }(a, b) + │ ^ + +The + operator expects arguments of this type: + + Int + +But this argument has this type: + + String + +Hint: Strings can be joined using the `append` or `concat` functions from the +`gleam/string` module. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__recursive_type.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__recursive_type.snap index 422b82bfa..cabb9cf3a 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__recursive_type.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__functions__recursive_type.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/functions.rs +assertion_line: 159 expression: "\npub fn one(x) {\n two([x])\n}\n\npub fn two(x) {\n one(x)\n}\n" --- error: Recursive type @@ -8,7 +9,7 @@ error: Recursive type 3 │ two([x]) │ ^^^ -I don't know how to work out what type this value has. It seems -to be defined in terms of itself. +I don't know how to work out what type this value has. It seems to be +defined in terms of itself. Hint: Add some type annotations and try again. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__import_type_duplicate.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__import_type_duplicate.snap index 95120d399..8076640d9 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__import_type_duplicate.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__import_type_duplicate.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one.{One, type One}\n\npub fn main() -> One {\n todo\n}\n" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:1:13 │ 1 │ import one.{One, type One} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__module_alias_used_as_a_name.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__module_alias_used_as_a_name.snap new file mode 100644 index 000000000..1a0c9fbb7 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__module_alias_used_as_a_name.snap @@ -0,0 +1,12 @@ +--- +source: compiler-core/src/type_/tests/imports.rs +expression: "\nimport one/two\n\npub fn main() {\n two\n}\n" +--- +error: Module `two` used as a value + ┌─ /src/one/two.gleam:5:3 + │ +5 │ two + │ ^^^ + +Modules are not values, so you cannot assign them to variables, pass them +to functions, or anything else that you would do with a value. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_import_errors_do_not_block_later_unqualified.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_import_errors_do_not_block_later_unqualified.snap index d76d7d091..5d51aff74 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_import_errors_do_not_block_later_unqualified.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_import_errors_do_not_block_later_unqualified.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import gleam.{Unknown, type Int as Integer}\n\npub fn main() -> Integer {\n Nil\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:1:15 │ 1 │ import gleam.{Unknown, type Int as Integer} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_opaque_constructo.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_opaque_constructo.snap index 665a2e679..dff15b955 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_opaque_constructo.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_opaque_constructo.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one.{Two}\n\npub fn main() {\n Two\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:1:13 │ 1 │ import one.{Two} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_constructo.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_constructo.snap index 3551c4438..736aff555 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_constructo.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_constructo.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one.{Two}\n\npub fn main() {\n Two\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:1:13 │ 1 │ import one.{Two} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_constructor_pattern.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_constructor_pattern.snap index a08baf14f..097eacc41 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_constructor_pattern.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_constructor_pattern.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one.{Two}\n\npub fn main(x) {\n let Two = x\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:1:13 │ 1 │ import one.{Two} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_function.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_function.snap index 1a0996479..c7d0b85b0 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_function.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__unqualified_using_private_function.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one.{two}\n\npub fn main() {\n two\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:1:13 │ 1 │ import one.{two} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_opaque_constructo.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_opaque_constructo.snap index e065c5903..5b81d6d60 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_opaque_constructo.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_opaque_constructo.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one\n\npub fn main() {\n one.Two\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:4:6 │ 4 │ one.Two diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_constructo.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_constructo.snap index e065c5903..5b81d6d60 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_constructo.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_constructo.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one\n\npub fn main() {\n one.Two\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:4:6 │ 4 │ one.Two diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_constructor_pattern.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_constructor_pattern.snap index e0a304c44..26aac0c69 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_constructor_pattern.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_constructor_pattern.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one\n\npub fn main(x) {\n let one.Two = x\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:4:7 │ 4 │ let one.Two = x diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_custom_type.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_custom_type.snap index c4f13a47c..e92a44857 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_custom_type.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_custom_type.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one\n\npub fn main() {\n one.X\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:4:6 │ 4 │ one.X diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_external_type.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_external_type.snap index c4f13a47c..e92a44857 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_external_type.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_external_type.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one\n\npub fn main() {\n one.X\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:4:6 │ 4 │ one.X diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_function.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_function.snap index 86ca098b9..a4f430ae9 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_function.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_function.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one\n\npub fn main() {\n one.two\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:4:6 │ 4 │ one.two diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_type_alias.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_type_alias.snap index c4f13a47c..e92a44857 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_type_alias.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_type_alias.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one\n\npub fn main() {\n one.X\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:4:6 │ 4 │ one.X diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_custom_type.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_custom_type.snap index afbd5eacd..67cf6848d 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_custom_type.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_custom_type.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one.{X}\n\npub fn main() {\n X\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:1:13 │ 1 │ import one.{X} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_external_type.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_external_type.snap index afbd5eacd..67cf6848d 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_external_type.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_external_type.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one.{X}\n\npub fn main() {\n X\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:1:13 │ 1 │ import one.{X} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_type_alias.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_type_alias.snap index afbd5eacd..67cf6848d 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_type_alias.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__imports__using_private_unqualified_type_alias.snap @@ -2,7 +2,7 @@ source: compiler-core/src/type_/tests/imports.rs expression: "import one.{X}\n\npub fn main() {\n X\n}" --- -error: Unknown module field +error: Unknown module value ┌─ /src/one/two.gleam:1:13 │ 1 │ import one.{X} diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__pipes__pipe_callback_wrong_arity.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__pipes__pipe_callback_wrong_arity.snap new file mode 100644 index 000000000..311a542b0 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__pipes__pipe_callback_wrong_arity.snap @@ -0,0 +1,9 @@ +--- +source: compiler-core/src/type_/tests/pipes.rs +expression: "\nfn callback(a: Int) {\n fn() -> String {\n \"Called\"\n }\n}\n\npub fn main() {\n let x = 1 |> callback(2)\n}\n" +--- +error: Incorrect arity + ┌─ /src/one/two.gleam:9:16 + │ +9 │ let x = 1 |> callback(2) + │ ^^^^^^^^^^^ Expected no arguments, got 1 diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__use___use_with_function_that_doesnt_take_callback_as_last_arg_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__use___use_with_function_that_doesnt_take_callback_as_last_arg_2.snap index 877c45ff0..ce4f67c99 100644 --- a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__use___use_with_function_that_doesnt_take_callback_as_last_arg_2.snap +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__use___use_with_function_that_doesnt_take_callback_as_last_arg_2.snap @@ -1,5 +1,6 @@ --- source: compiler-core/src/type_/tests/use_.rs +assertion_line: 126 expression: "\nlet f = fn() { 1 }\nuse <- f\n123\n" --- error: Incorrect arity @@ -8,7 +9,7 @@ error: Incorrect arity 3 │ use <- f │ ^ Expected no arguments, got 1 -The function on the right of `<-` here takes no arguments. -But it has to take at least one argument, a callback function. +The function on the right of `<-` here takes no arguments, but it has to +take at least one argument, a callback function. See: https://tour.gleam.run/advanced-features/use/ diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__constant_string_concatenation_requires_v1_4.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__constant_string_concatenation_requires_v1_4.snap new file mode 100644 index 000000000..18472261e --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__constant_string_concatenation_requires_v1_4.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "pub const string = \"wibble\" <> \"wobble\"" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:1:20 + │ +1 │ pub const string = "wibble" <> "wobble" + │ ^^^^^^^^^^^^^^^^^^^^ This requires a Gleam version >= 1.4.0 + +Constant strings concatenation was introduced in version v1.4.0. But the +Gleam version range specified in your `gleam.toml` would allow this code to +run on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.4.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax.snap new file mode 100644 index 000000000..078113ed6 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax.snap @@ -0,0 +1,11 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub type Wibble {\n Wibble(one: Int, two: Int)\n}\n\npub fn main() {\n let wibble = Wibble(one: 1, two: 2)\n case wibble {\n Wibble(one: one ..) -> one\n }\n}\n" +--- +warning: Deprecated record pattern matching syntax + ┌─ test/path:9:21 + │ +9 │ Wibble(one: one ..) -> one + │ ^^ This should be preceded by a comma + +This syntax for pattern matching on a record is deprecated. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax_with_label_shorthand.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax_with_label_shorthand.snap new file mode 100644 index 000000000..74e231385 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax_with_label_shorthand.snap @@ -0,0 +1,11 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub type Wibble {\n Wibble(one: Int, two: Int)\n}\n\npub fn main() {\n let wibble = Wibble(one: 1, two: 2)\n case wibble {\n Wibble(one: ..) -> one\n }\n}\n" +--- +warning: Deprecated record pattern matching syntax + ┌─ test/path:9:17 + │ +9 │ Wibble(one: ..) -> one + │ ^^ This should be preceded by a comma + +This syntax for pattern matching on a record is deprecated. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax_with_no_labels.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax_with_no_labels.snap new file mode 100644 index 000000000..7d6486729 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__deprecated_record_pattern_syntax_with_no_labels.snap @@ -0,0 +1,11 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub type Wibble {\n Wibble(one: Int, two: Int)\n}\n\npub fn main() {\n let wibble = Wibble(one: 1, two: 2)\n case wibble {\n Wibble(one ..) -> one\n }\n}\n" +--- +warning: Deprecated record pattern matching syntax + ┌─ test/path:9:16 + │ +9 │ Wibble(one ..) -> one + │ ^^ This should be preceded by a comma + +This syntax for pattern matching on a record is deprecated. diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_divide_in_guards_requires_v1_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_divide_in_guards_requires_v1_3.snap new file mode 100644 index 000000000..be611f751 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_divide_in_guards_requires_v1_3.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n case Nil {\n _ if 1.0 /. 1.0 == 0.0 -> Nil\n _ -> Nil\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:8 + │ +4 │ _ if 1.0 /. 1.0 == 0.0 -> Nil + │ ^^^^^^^^^^ This requires a Gleam version >= 1.3.0 + +Arithmetic operations in guards were introduced in version v1.3.0. But the +Gleam version range specified in your `gleam.toml` would allow this code to +run on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.3.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_minus_in_guards_requires_v1_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_minus_in_guards_requires_v1_3.snap new file mode 100644 index 000000000..9b57f5162 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_minus_in_guards_requires_v1_3.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n case Nil {\n _ if 1.0 -. 1.0 == 0.0 -> Nil\n _ -> Nil\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:10 + │ +4 │ _ if 1.0 -. 1.0 == 0.0 -> Nil + │ ^^^^^^^^^^ This requires a Gleam version >= 1.3.0 + +Arithmetic operations in guards were introduced in version v1.3.0. But the +Gleam version range specified in your `gleam.toml` would allow this code to +run on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.3.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_multiplication_in_guards_requires_v1_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_multiplication_in_guards_requires_v1_3.snap new file mode 100644 index 000000000..2e045eafc --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_multiplication_in_guards_requires_v1_3.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n case Nil {\n _ if 1.0 *. 1.0 == 0.0 -> Nil\n _ -> Nil\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:8 + │ +4 │ _ if 1.0 *. 1.0 == 0.0 -> Nil + │ ^^^^^^^^^^ This requires a Gleam version >= 1.3.0 + +Arithmetic operations in guards were introduced in version v1.3.0. But the +Gleam version range specified in your `gleam.toml` would allow this code to +run on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.3.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_plus_in_guards_requires_v1_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_plus_in_guards_requires_v1_3.snap new file mode 100644 index 000000000..c9b4cbe54 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__float_plus_in_guards_requires_v1_3.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n case Nil {\n _ if 1.0 +. 1.0 == 2.0 -> Nil\n _ -> Nil\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:10 + │ +4 │ _ if 1.0 +. 1.0 == 2.0 -> Nil + │ ^^^^^^^^^^ This requires a Gleam version >= 1.3.0 + +Arithmetic operations in guards were introduced in version v1.3.0. But the +Gleam version range specified in your `gleam.toml` would allow this code to +run on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.3.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_divide_in_guards_requires_v1_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_divide_in_guards_requires_v1_3.snap new file mode 100644 index 000000000..39930a02c --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_divide_in_guards_requires_v1_3.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n case Nil {\n _ if 1 / 1 == 0 -> Nil\n _ -> Nil\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:8 + │ +4 │ _ if 1 / 1 == 0 -> Nil + │ ^^^^^ This requires a Gleam version >= 1.3.0 + +Arithmetic operations in guards were introduced in version v1.3.0. But the +Gleam version range specified in your `gleam.toml` would allow this code to +run on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.3.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_minus_in_guards_requires_v1_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_minus_in_guards_requires_v1_3.snap new file mode 100644 index 000000000..5d7ff3bca --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_minus_in_guards_requires_v1_3.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n case Nil {\n _ if 1 - 1 == 0 -> Nil\n _ -> Nil\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:10 + │ +4 │ _ if 1 - 1 == 0 -> Nil + │ ^^^^^ This requires a Gleam version >= 1.3.0 + +Arithmetic operations in guards were introduced in version v1.3.0. But the +Gleam version range specified in your `gleam.toml` would allow this code to +run on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.3.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_multiplication_in_guards_requires_v1_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_multiplication_in_guards_requires_v1_3.snap new file mode 100644 index 000000000..b3f8f7af5 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_multiplication_in_guards_requires_v1_3.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n case Nil {\n _ if 1 * 1 == 0 -> Nil\n _ -> Nil\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:8 + │ +4 │ _ if 1 * 1 == 0 -> Nil + │ ^^^^^ This requires a Gleam version >= 1.3.0 + +Arithmetic operations in guards were introduced in version v1.3.0. But the +Gleam version range specified in your `gleam.toml` would allow this code to +run on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.3.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_plus_in_guards_requires_v1_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_plus_in_guards_requires_v1_3.snap new file mode 100644 index 000000000..49c2bcef1 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_plus_in_guards_requires_v1_3.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n case Nil {\n _ if 1 + 1 == 2 -> Nil\n _ -> Nil\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:10 + │ +4 │ _ if 1 + 1 == 2 -> Nil + │ ^^^^^ This requires a Gleam version >= 1.3.0 + +Arithmetic operations in guards were introduced in version v1.3.0. But the +Gleam version range specified in your `gleam.toml` would allow this code to +run on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.3.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_remainder_in_guards_requires_v1_3.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_remainder_in_guards_requires_v1_3.snap new file mode 100644 index 000000000..d13a46d58 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__int_remainder_in_guards_requires_v1_3.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n case Nil {\n _ if 1 % 1 == 0 -> Nil\n _ -> Nil\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:8 + │ +4 │ _ if 1 % 1 == 0 -> Nil + │ ^^^^^ This requires a Gleam version >= 1.3.0 + +Arithmetic operations in guards were introduced in version v1.3.0. But the +Gleam version range specified in your `gleam.toml` would allow this code to +run on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.3.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_constant_requires_v1_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_constant_requires_v1_1.snap new file mode 100644 index 000000000..c4937adf0 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_constant_requires_v1_1.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\n@internal\npub const wibble = 1\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:2:1 + │ +2 │ @internal + │ ^^^^^^^^^ This requires a Gleam version >= 1.1.0 + +The `@internal` annotation was introduced in version v1.1.0. But the Gleam +version range specified in your `gleam.toml` would allow this code to run +on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.1.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_function_requires_v1_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_function_requires_v1_1.snap new file mode 100644 index 000000000..662ed0f1f --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_function_requires_v1_1.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\n@internal\npub fn wibble() { Nil }\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:2:1 + │ +2 │ @internal + │ ^^^^^^^^^ This requires a Gleam version >= 1.1.0 + +The `@internal` annotation was introduced in version v1.1.0. But the Gleam +version range specified in your `gleam.toml` would allow this code to run +on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.1.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_type_requires_v1_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_type_requires_v1_1.snap new file mode 100644 index 000000000..1e2b5b6e4 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__internal_annotation_on_type_requires_v1_1.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\n@internal\npub type Wibble\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:2:1 + │ +2 │ @internal + │ ^^^^^^^^^ This requires a Gleam version >= 1.1.0 + +The `@internal` annotation was introduced in version v1.1.0. But the Gleam +version range specified in your `gleam.toml` would allow this code to run +on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.1.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__javascript_external_module_with_at_requires_v1_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__javascript_external_module_with_at_requires_v1_2.snap new file mode 100644 index 000000000..21e096b1e --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__javascript_external_module_with_at_requires_v1_2.snap @@ -0,0 +1,17 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\n@external(javascript, \"module@module\", \"func\")\npub fn main() { Nil }\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:2:1 + │ +2 │ @external(javascript, "module@module", "func") + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This requires a Gleam version >= 1.2.0 + +The ability to have `@` in a Javascript module's name was introduced in +version v1.2.0. But the Gleam version range specified in your `gleam.toml` +would allow this code to run on an earlier version like v1.0.0, resulting +in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.2.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_call_requires_v1_4.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_call_requires_v1_4.snap new file mode 100644 index 000000000..34bfcc01b --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_call_requires_v1_4.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub type Wibble { Wibble(wibble: Int) }\n\npub fn main() {\n let wibble = 1\n Wibble(wibble:)\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:6:10 + │ +6 │ Wibble(wibble:) + │ ^^^^^^^ This requires a Gleam version >= 1.4.0 + +The label shorthand syntax was introduced in version v1.4.0. But the Gleam +version range specified in your `gleam.toml` would allow this code to run +on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.4.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_constand_requires_v1_4.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_constand_requires_v1_4.snap new file mode 100644 index 000000000..f58aceddd --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_constand_requires_v1_4.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub type Wibble { Wibble(wibble: Int) }\n\npub const wibble = 1\npub const wobble = Wibble(wibble:)\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:5:27 + │ +5 │ pub const wobble = Wibble(wibble:) + │ ^^^^^^^ This requires a Gleam version >= 1.4.0 + +The label shorthand syntax was introduced in version v1.4.0. But the Gleam +version range specified in your `gleam.toml` would allow this code to run +on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.4.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_pattern_requires_v1_4.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_pattern_requires_v1_4.snap new file mode 100644 index 000000000..2ca932c72 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__label_shorthand_in_pattern_requires_v1_4.snap @@ -0,0 +1,16 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub type Wibble { Wibble(wibble: Int) }\n\npub fn main(wibble) {\n case wibble {\n Wibble(wibble:) -> wibble\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:6:12 + │ +6 │ Wibble(wibble:) -> wibble + │ ^^^^^^^ This requires a Gleam version >= 1.4.0 + +The label shorthand syntax was introduced in version v1.4.0. But the Gleam +version range specified in your `gleam.toml` would allow this code to run +on an earlier version like v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.4.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_constant_segment_requires_v1_5.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_constant_segment_requires_v1_5.snap new file mode 100644 index 000000000..94d6960f6 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_constant_segment_requires_v1_5.snap @@ -0,0 +1,17 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "pub const bits = <<\"hello\">>" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:1:20 + │ +1 │ pub const bits = <<"hello">> + │ ^^^^^^^ This requires a Gleam version >= 1.5.0 + +The ability to omit the `utf8` annotation for string segments was +introduced in version v1.5.0. But the Gleam version range specified in +your `gleam.toml` would allow this code to run on an earlier version like +v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.5.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_pattern_segment_requires_v1_5.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_pattern_segment_requires_v1_5.snap new file mode 100644 index 000000000..bdf2ba87a --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_pattern_segment_requires_v1_5.snap @@ -0,0 +1,17 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main(a) {\n case a {\n <<\"hello\">> -> Nil\n _ -> Nil\n }\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:7 + │ +4 │ <<"hello">> -> Nil + │ ^^^^^^^ This requires a Gleam version >= 1.5.0 + +The ability to omit the `utf8` annotation for string segments was +introduced in version v1.5.0. But the Gleam version range specified in +your `gleam.toml` would allow this code to run on an earlier version like +v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.5.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_segment_requires_v1_5.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_segment_requires_v1_5.snap new file mode 100644 index 000000000..684782a6d --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__missing_utf_8_option_in_bit_array_segment_requires_v1_5.snap @@ -0,0 +1,17 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n <<\"hello\">>\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:3:5 + │ +3 │ <<"hello">> + │ ^^^^^^^ This requires a Gleam version >= 1.5.0 + +The ability to omit the `utf8` annotation for string segments was +introduced in version v1.5.0. But the Gleam version range specified in +your `gleam.toml` would allow this code to run on an earlier version like +v1.0.0, resulting in compilation errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.5.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__nested_tuple_access_requires_v1_1.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__nested_tuple_access_requires_v1_1.snap new file mode 100644 index 000000000..ac37c1403 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__nested_tuple_access_requires_v1_1.snap @@ -0,0 +1,17 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\npub fn main() {\n let tuple = #(1, #(1, 1))\n tuple.1.0\n}\n" +--- +warning: Incompatible gleam version range + ┌─ /src/warning/wrn.gleam:4:3 + │ +4 │ tuple.1.0 + │ ^^^^^^^^^ This requires a Gleam version >= 1.1.0 + +The ability to access nested tuple fields was introduced in version v1.1.0. +But the Gleam version range specified in your `gleam.toml` would allow this +code to run on an earlier version like v1.0.0, resulting in compilation +errors! +Hint: Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = ">= 1.1.0" diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__unused_module_select_constructor.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__unused_module_select_constructor.snap new file mode 100644 index 000000000..1bdc8b802 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__unused_module_select_constructor.snap @@ -0,0 +1,9 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\nimport wibble\n\npub fn main() {\n wibble.Wibble(1)\n 1\n}\n" +--- +warning: Unused value + ┌─ /src/warning/wrn.gleam:5:3 + │ +5 │ wibble.Wibble(1) + │ ^^^^^^^^^^^^^^^^ This value is never used diff --git a/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__unused_pipeline_ending_with_variant_raises_a_warning_2.snap b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__unused_pipeline_ending_with_variant_raises_a_warning_2.snap new file mode 100644 index 000000000..a52255378 --- /dev/null +++ b/compiler-core/src/type_/tests/snapshots/glistix_core__type___tests__warnings__unused_pipeline_ending_with_variant_raises_a_warning_2.snap @@ -0,0 +1,9 @@ +--- +source: compiler-core/src/type_/tests/warnings.rs +expression: "\nimport wibble\n\npub fn wobble(a) { a }\n\npub fn main() {\n 1 |> wobble |> wibble.Wibble\n 1\n}\n" +--- +warning: Unused value + ┌─ /src/warning/wrn.gleam:7:3 + │ +7 │ 1 |> wobble |> wibble.Wibble + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This value is never used diff --git a/compiler-core/src/type_/tests/target_implementations.rs b/compiler-core/src/type_/tests/target_implementations.rs index dc6c851bc..ad3f56753 100644 --- a/compiler-core/src/type_/tests/target_implementations.rs +++ b/compiler-core/src/type_/tests/target_implementations.rs @@ -26,6 +26,7 @@ pub fn implementations(src: &str) -> Vec<(EcoString, Implementations)> { vec![], Target::Erlang, TargetSupport::NotEnforced, + None, ) .expect("compile src") .type_info @@ -350,6 +351,7 @@ pub fn no_valid_erlang_impl() { vec![], Target::Erlang, TargetSupport::Enforced, + None, ); assert!(out.is_err()); } @@ -376,6 +378,7 @@ pub fn no_valid_javascript_impl() { vec![], Target::JavaScript, TargetSupport::Enforced, + None, ); assert!(out.is_err()); } @@ -402,6 +405,7 @@ pub fn no_valid_erlang_impl() { vec![], Target::Erlang, TargetSupport::Enforced, + None, ); assert!(out.is_err()); } @@ -428,6 +432,7 @@ pub fn no_valid_javascript_impl() { vec![], Target::JavaScript, TargetSupport::Enforced, + None, ); assert!(out.is_err()); } @@ -450,6 +455,7 @@ pub fn no_valid_erlang_impl() { vec![], Target::Erlang, TargetSupport::Enforced, + None, ); assert!(out.is_err()); } @@ -472,6 +478,7 @@ pub fn no_valid_javascript_impl() { vec![], Target::JavaScript, TargetSupport::Enforced, + None, ); assert!(out.is_err()); } diff --git a/compiler-core/src/type_/tests/version_inference.rs b/compiler-core/src/type_/tests/version_inference.rs new file mode 100644 index 000000000..b66a6d9d6 --- /dev/null +++ b/compiler-core/src/type_/tests/version_inference.rs @@ -0,0 +1,315 @@ +use hexpm::version::Version; + +use super::compile_module; + +fn infer_version(module: &str) -> Version { + compile_module("test_module", module, None, vec![]) + .expect("module to compile") + .type_info + .minimum_required_version +} + +#[test] +fn internal_annotation_on_constant_requires_v1_1() { + let version = infer_version( + " +@internal +pub const wibble = 1 +", + ); + assert_eq!(version, Version::new(1, 1, 0)); +} + +#[test] +fn internal_annotation_on_type_requires_v1_1() { + let version = infer_version( + " +@internal +pub type Wibble +", + ); + assert_eq!(version, Version::new(1, 1, 0)); +} + +#[test] +fn internal_annotation_on_function_requires_v1_1() { + let version = infer_version( + " +@internal +pub fn wibble() {} +", + ); + assert_eq!(version, Version::new(1, 1, 0)); +} + +#[test] +fn nested_tuple_access_requires_v1_1() { + let version = infer_version( + " +pub fn main() { + let tuple = #(1, #(1, 1)) + tuple.1.0 +} +", + ); + assert_eq!(version, Version::new(1, 1, 0)); +} + +#[test] +fn javascript_external_module_with_at_requires_v1_2() { + let version = infer_version( + " +@external(javascript, \"module@module\", \"func\") +pub fn main() {} +", + ); + assert_eq!(version, Version::new(1, 2, 0)); +} + +#[test] +fn int_plus_in_guards_requires_v1_3() { + let version = infer_version( + " +pub fn main() { + case todo { + _ if 1 + 1 == 2 -> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 3, 0)); +} + +#[test] +fn float_plus_in_guards_requires_v1_3() { + let version = infer_version( + " +pub fn main() { + case todo { + _ if 1.0 +. 1.0 == 2.0 -> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 3, 0)); +} + +#[test] +fn int_minus_in_guards_requires_v1_3() { + let version = infer_version( + " +pub fn main() { + case todo { + _ if 1 - 1 == 0 -> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 3, 0)); +} + +#[test] +fn float_minus_in_guards_requires_v1_3() { + let version = infer_version( + " +pub fn main() { + case todo { + _ if 1.0 -. 1.0 == 0.0 -> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 3, 0)); +} + +#[test] +fn int_multiplication_in_guards_requires_v1_3() { + let version = infer_version( + " +pub fn main() { + case todo { + _ if 1 * 1 == 0 -> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 3, 0)); +} + +#[test] +fn float_multiplication_in_guards_requires_v1_3() { + let version = infer_version( + " +pub fn main() { + case todo { + _ if 1.0 *. 1.0 == 0.0 -> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 3, 0)); +} + +#[test] +fn int_divide_in_guards_requires_v1_3() { + let version = infer_version( + " +pub fn main() { + case todo { + _ if 1 / 1 == 0 -> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 3, 0)); +} + +#[test] +fn float_divide_in_guards_requires_v1_3() { + let version = infer_version( + " +pub fn main() { + case todo { + _ if 1.0 /. 1.0 == 0.0 -> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 3, 0)); +} + +#[test] +fn int_remainder_in_guards_requires_v1_3() { + let version = infer_version( + " +pub fn main() { + case todo { + _ if 1 % 1 == 0 -> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 3, 0)); +} + +#[test] +fn label_shorthand_in_constand_requires_v1_4() { + let version = infer_version( + " +pub type Wibble { Wibble(wibble: Int) } + +pub const wibble = 1 +pub const wobble = Wibble(wibble:) +", + ); + assert_eq!(version, Version::new(1, 4, 0)); +} + +#[test] +fn label_shorthand_in_call_requires_v1_4() { + let version = infer_version( + " +pub type Wibble { Wibble(wibble: Int) } + +pub fn main() { + let wibble = 1 + Wibble(wibble:) +} +", + ); + assert_eq!(version, Version::new(1, 4, 0)); +} + +#[test] +fn label_shorthand_in_pattern_requires_v1_4() { + let version = infer_version( + " +pub type Wibble { Wibble(wibble: Int) } + +pub fn main() { + case Wibble(1) { + Wibble(wibble:) -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 4, 0)); +} + +#[test] +fn constant_string_concatenation_requires_v1_4() { + let version = infer_version("pub const string = \"wibble\" <> \"wobble\""); + assert_eq!(version, Version::new(1, 4, 0)); +} + +#[test] +fn missing_utf_8_option_in_bit_array_segment_requires_v1_5() { + let version = infer_version( + " +pub fn main() { + <<\"hello\", \" world!\">> +} +", + ); + assert_eq!(version, Version::new(1, 5, 0)); +} + +#[test] +fn missing_utf_8_option_in_bit_array_constant_segment_requires_v1_5() { + let version = infer_version("const bits = <<\"hello\", \" world!\">>"); + assert_eq!(version, Version::new(1, 5, 0)); +} + +#[test] +fn missing_utf_8_option_in_bit_array_pattern_segment_requires_v1_5() { + let version = infer_version( + " +pub fn main() { + case todo { + <<\"hello\", \" world!\">> -> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 5, 0)); +} + +#[test] +fn inference_picks_the_bigger_of_two_versions() { + let version = infer_version( + " +pub fn main() { + case todo { + <<\"hello\", \" world!\">> -> todo + _ if 1 + 1 == 2-> todo + _ -> todo + } +} +", + ); + assert_eq!(version, Version::new(1, 5, 0)); +} + +#[test] +fn inference_picks_the_bigger_of_two_versions_2() { + let version = infer_version( + " +@external(javascript, \"module@module\", \"func\") +pub fn main() { + let tuple = #(1, #(1, 1)) + tuple.1.0 +} +", + ); + assert_eq!(version, Version::new(1, 2, 0)); +} diff --git a/compiler-core/src/type_/tests/warnings.rs b/compiler-core/src/type_/tests/warnings.rs index 25388a8ab..2a3172f6a 100644 --- a/compiler-core/src/type_/tests/warnings.rs +++ b/compiler-core/src/type_/tests/warnings.rs @@ -1,5 +1,8 @@ use super::*; -use crate::{assert_no_warnings, assert_warning, assert_warnings_with_imports}; +use crate::{ + assert_no_warnings, assert_warning, assert_warnings_with_gleam_version, + assert_warnings_with_imports, +}; #[test] fn unknown_label() { @@ -787,7 +790,7 @@ pub fn main() { x }"#; let warnings = VectorWarningEmitterIO::default(); - _ = compile_module("test_module", src, Some(Arc::new(warnings.clone())), vec![]).unwrap_err(); + _ = compile_module("test_module", src, Some(Rc::new(warnings.clone())), vec![]).unwrap_err(); assert!(warnings.take().is_empty()); } @@ -1332,6 +1335,23 @@ pub fn main() { ); } +#[test] +fn unused_pipeline_ending_with_variant_raises_a_warning_2() { + assert_warning!( + ("wibble", "pub type Wibble { Wibble(Int) }"), + r#" +import wibble + +pub fn wobble(a) { a } + +pub fn main() { + 1 |> wobble |> wibble.Wibble + 1 +} +"# + ); +} + #[test] fn unused_pipeline_not_ending_with_variant_raises_no_warnings() { assert_no_warnings!( @@ -1347,6 +1367,21 @@ pub fn main() { ); } +#[test] +fn unused_module_select_constructor() { + assert_warning!( + ("wibble", "pub type Wibble { Wibble(Int) }"), + r#" +import wibble + +pub fn main() { + wibble.Wibble(1) + 1 +} +"# + ); +} + /* TODO: These tests are commented out until we figure out a better way to deal @@ -1986,6 +2021,97 @@ fn deprecated_list_pattern_syntax_1() { ); } +// https://github.com/gleam-lang/gleam/issues/3473 +#[test] +fn deprecated_record_pattern_syntax() { + assert_warning!( + r#" +pub type Wibble { + Wibble(one: Int, two: Int) +} + +pub fn main() { + let wibble = Wibble(one: 1, two: 2) + case wibble { + Wibble(one: one ..) -> one + } +} +"# + ); +} + +#[test] +fn deprecated_record_pattern_syntax_with_no_labels() { + assert_warning!( + r#" +pub type Wibble { + Wibble(one: Int, two: Int) +} + +pub fn main() { + let wibble = Wibble(one: 1, two: 2) + case wibble { + Wibble(one ..) -> one + } +} +"# + ); +} + +#[test] +fn deprecated_record_pattern_syntax_with_label_shorthand() { + assert_warning!( + r#" +pub type Wibble { + Wibble(one: Int, two: Int) +} + +pub fn main() { + let wibble = Wibble(one: 1, two: 2) + case wibble { + Wibble(one: ..) -> one + } +} +"# + ); +} + +#[test] +fn deprecated_record_pattern_syntax_has_no_warning_if_everything_is_discarded() { + assert_no_warnings!( + r#" +pub type Wibble { + Wibble(one: Int, two: Int) +} + +pub fn main() { + let wibble = Wibble(one: 1, two: 2) + case wibble { + Wibble(..) -> 1 + } +} +"# + ); +} + +#[test] +fn deprecated_record_pattern_syntax_has_no_warning_if_there_is_a_comma_before_spread() { + assert_no_warnings!( + r#" +pub type Wibble { + Wibble(one: Int, two: Int) +} + +pub fn main() { + let wibble = Wibble(one: 1, two: 2) + case wibble { + Wibble(one: one, ..) -> one + } +} +"# + ); +} + #[test] fn unused_label_shorthand_pattern_arg() { assert_warning!( @@ -2014,3 +2140,282 @@ pub fn main() { "# ); } + +#[test] +fn internal_annotation_on_constant_requires_v1_1() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +@internal +pub const wibble = 1 +", + ); +} + +#[test] +fn internal_annotation_on_type_requires_v1_1() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +@internal +pub type Wibble +", + ); +} + +#[test] +fn internal_annotation_on_function_requires_v1_1() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +@internal +pub fn wibble() { Nil } +", + ); +} + +#[test] +fn nested_tuple_access_requires_v1_1() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + let tuple = #(1, #(1, 1)) + tuple.1.0 +} +", + ); +} + +#[test] +fn javascript_external_module_with_at_requires_v1_2() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +@external(javascript, \"module@module\", \"func\") +pub fn main() { Nil } +", + ); +} + +#[test] +fn int_plus_in_guards_requires_v1_3() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + case Nil { + _ if 1 + 1 == 2 -> Nil + _ -> Nil + } +} +", + ); +} + +#[test] +fn float_plus_in_guards_requires_v1_3() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + case Nil { + _ if 1.0 +. 1.0 == 2.0 -> Nil + _ -> Nil + } +} +", + ); +} + +#[test] +fn int_minus_in_guards_requires_v1_3() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + case Nil { + _ if 1 - 1 == 0 -> Nil + _ -> Nil + } +} +", + ); +} + +#[test] +fn float_minus_in_guards_requires_v1_3() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + case Nil { + _ if 1.0 -. 1.0 == 0.0 -> Nil + _ -> Nil + } +} +", + ); +} + +#[test] +fn int_multiplication_in_guards_requires_v1_3() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + case Nil { + _ if 1 * 1 == 0 -> Nil + _ -> Nil + } +} +", + ); +} + +#[test] +fn float_multiplication_in_guards_requires_v1_3() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + case Nil { + _ if 1.0 *. 1.0 == 0.0 -> Nil + _ -> Nil + } +} +", + ); +} + +#[test] +fn int_divide_in_guards_requires_v1_3() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + case Nil { + _ if 1 / 1 == 0 -> Nil + _ -> Nil + } +} +", + ); +} + +#[test] +fn float_divide_in_guards_requires_v1_3() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + case Nil { + _ if 1.0 /. 1.0 == 0.0 -> Nil + _ -> Nil + } +} +", + ); +} + +#[test] +fn int_remainder_in_guards_requires_v1_3() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + case Nil { + _ if 1 % 1 == 0 -> Nil + _ -> Nil + } +} +", + ); +} + +#[test] +fn label_shorthand_in_constand_requires_v1_4() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub type Wibble { Wibble(wibble: Int) } + +pub const wibble = 1 +pub const wobble = Wibble(wibble:) +", + ); +} + +#[test] +fn label_shorthand_in_call_requires_v1_4() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub type Wibble { Wibble(wibble: Int) } + +pub fn main() { + let wibble = 1 + Wibble(wibble:) +} +", + ); +} + +#[test] +fn label_shorthand_in_pattern_requires_v1_4() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub type Wibble { Wibble(wibble: Int) } + +pub fn main(wibble) { + case wibble { + Wibble(wibble:) -> wibble + } +} +", + ); +} + +#[test] +fn constant_string_concatenation_requires_v1_4() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + "pub const string = \"wibble\" <> \"wobble\"" + ); +} + +#[test] +fn missing_utf_8_option_in_bit_array_segment_requires_v1_5() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main() { + <<\"hello\">> +} +", + ); +} + +#[test] +fn missing_utf_8_option_in_bit_array_constant_segment_requires_v1_5() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + "pub const bits = <<\"hello\">>" + ); +} + +#[test] +fn missing_utf_8_option_in_bit_array_pattern_segment_requires_v1_5() { + assert_warnings_with_gleam_version!( + Range::higher_than(Version::new(1, 0, 0)), + " +pub fn main(a) { + case a { + <<\"hello\">> -> Nil + _ -> Nil + } +} +", + ); +} diff --git a/compiler-core/src/version.rs b/compiler-core/src/version.rs index 8db22f5a0..912cb0a6d 100644 --- a/compiler-core/src/version.rs +++ b/compiler-core/src/version.rs @@ -3,4 +3,4 @@ /// instead build from scratch /// Note that this should be updated to correspond to the Gleam version /// we are basing Glistix on. This is checked by packages. -pub const COMPILER_VERSION: &str = "1.4.1"; +pub const COMPILER_VERSION: &str = "1.5.0"; diff --git a/compiler-core/src/warning.rs b/compiler-core/src/warning.rs index f368fafd2..b23788aa7 100644 --- a/compiler-core/src/warning.rs +++ b/compiler-core/src/warning.rs @@ -4,18 +4,18 @@ use crate::{ error::wrap, type_::{ self, - error::{LiteralCollectionKind, PanicPosition, TodoOrPanic}, + error::{FeatureKind, LiteralCollectionKind, PanicPosition, TodoOrPanic}, pretty::Printer, }, }; use camino::Utf8PathBuf; use debug_ignore::DebugIgnore; use ecow::EcoString; -use std::sync::atomic::AtomicUsize; use std::{ io::Write, sync::{atomic::Ordering, Arc}, }; +use std::{rc::Rc, sync::atomic::AtomicUsize}; use termcolor::Buffer; pub trait WarningEmitterIO { @@ -73,11 +73,11 @@ pub struct WarningEmitter { /// package only, the count is reset back to zero after the dependencies are /// compiled. count: Arc, - emitter: DebugIgnore>, + emitter: DebugIgnore>, } impl WarningEmitter { - pub fn new(emitter: Arc) -> Self { + pub fn new(emitter: Rc) -> Self { Self { count: Arc::new(AtomicUsize::new(0)), emitter: DebugIgnore(emitter), @@ -85,7 +85,7 @@ impl WarningEmitter { } pub fn null() -> Self { - Self::new(Arc::new(NullWarningEmitterIO)) + Self::new(Rc::new(NullWarningEmitterIO)) } pub fn reset_count(&self) { @@ -101,10 +101,10 @@ impl WarningEmitter { self.emitter.emit_warning(warning); } - pub fn vector() -> (Self, Arc) { - let io = Arc::new(VectorWarningEmitterIO::default()); + pub fn vector() -> (Self, Rc) { + let io = Rc::new(VectorWarningEmitterIO::default()); let emitter = Self::new(io.clone()); - (emitter, Arc::clone(&io)) + (emitter, Rc::clone(&io)) } } @@ -128,7 +128,7 @@ impl TypeWarningEmitter { Self { module_path: Utf8PathBuf::new(), module_src: EcoString::from(""), - emitter: WarningEmitter::new(Arc::new(NullWarningEmitterIO)), + emitter: WarningEmitter::new(Rc::new(NullWarningEmitterIO)), } } @@ -188,6 +188,16 @@ pub enum DeprecatedSyntaxWarning { /// ``` /// DeprecatedListCatchAllPattern { location: SrcSpan }, + + /// If a record pattern has a spread that is not preceded by a comma: + /// ```gleam + /// case wibble { + /// Wibble(arg1: name ..) -> todo + /// // ^^ this should be preceded by a comma! + /// } + /// ``` + /// + DeprecatedRecordSpreadPattern { location: SrcSpan }, } impl Warning { @@ -255,6 +265,26 @@ like this: `[item, ..list]`.", }), }, + Warning::DeprecatedSyntax { + path, + src, + warning: DeprecatedSyntaxWarning::DeprecatedRecordSpreadPattern { location }, + } => Diagnostic { + title: "Deprecated record pattern matching syntax".into(), + text: wrap("This syntax for pattern matching on a record is deprecated."), + hint: None, + level: diagnostic::Level::Warning, + location: Some(Location { + label: diagnostic::Label { + text: Some("This should be preceded by a comma".into()), + span: *location, + }, + path: path.clone(), + src: src.clone(), + extra_labels: vec![], + }), + }, + Warning::DeprecatedSyntax { path, src, @@ -282,7 +312,7 @@ To match on all possible lists, use the `_` catch-all pattern instead.", type_::Warning::Todo { kind, location, - typ, + type_, } => { let mut text = String::new(); text.push_str( @@ -303,10 +333,10 @@ expression.", } } .into(); - if !typ.is_variable() { + if !type_.is_variable() { text.push_str(&format!( "\n\nHint: I think its type is `{}`.\n", - Printer::new().pretty_print(typ, 0) + Printer::new().pretty_print(type_, 0) )); } @@ -966,15 +996,67 @@ See: https://tour.gleam.run/functions/pipelines/", extra_labels: vec![], }), }, + type_::Warning::FeatureRequiresHigherGleamVersion { + location, + minimum_required_version, + wrongfully_allowed_version, + feature_kind, + } => { + let feature = match feature_kind { + FeatureKind::LabelShorthandSyntax => "The label shorthand syntax was", + FeatureKind::ConstantStringConcatenation => { + "Constant strings concatenation was" + } + FeatureKind::ArithmeticInGuards => "Arithmetic operations in guards were", + FeatureKind::UnannotatedUtf8StringSegment => { + "The ability to omit the `utf8` annotation for string segments was" + } + FeatureKind::NestedTupleAccess => { + "The ability to access nested tuple fields was" + } + FeatureKind::InternalAnnotation => "The `@internal` annotation was", + FeatureKind::AtInJavascriptModules => { + "The ability to have `@` in a Javascript module's name was" + } + }; + + Diagnostic { + title: "Incompatible gleam version range".into(), + text: wrap(&format!( + "{feature} introduced in version v{minimum_required_version}. But the Gleam version range \ + specified in your `gleam.toml` would allow this code to run on an earlier \ + version like v{wrongfully_allowed_version}, resulting in compilation errors!", + )), + hint: Some(format!( + "Remove the version constraint from your `gleam.toml` or update it to be: + + gleam = \">= {}\"", + minimum_required_version + )), + level: diagnostic::Level::Warning, + location: Some(Location { + label: diagnostic::Label { + text: Some(format!( + "This requires a Gleam version >= {}", + minimum_required_version + )), + span: *location, + }, + path: path.clone(), + src: src.clone(), + extra_labels: vec![], + }), + } + } }, } } pub fn pretty(&self, buffer: &mut Buffer) { + self.to_diagnostic().write(buffer); buffer .write_all(b"\n") - .expect("error pretty buffer write space before"); - self.to_diagnostic().write(buffer); + .expect("error pretty buffer write space after"); } pub fn to_pretty_string(&self) -> String { diff --git a/compiler-core/templates/docs-css/index.css b/compiler-core/templates/docs-css/index.css index b123ff196..4199c073b 100644 --- a/compiler-core/templates/docs-css/index.css +++ b/compiler-core/templates/docs-css/index.css @@ -419,6 +419,7 @@ p a code { padding-top: var(--gap); padding-bottom: calc(3 * var(--gap)); padding-left: var(--gap); + padding-right: var(--gap); position: fixed; top: var(--header-height); transition: transform 0.5s ease; @@ -441,6 +442,13 @@ p a code { margin-bottom: 4px; } +.module-link { + display: inline-block; + padding-left: 0.5em; + text-indent: -0.5em; + line-height: 1.2; +} + .sidebar .sidebar-toggle { color: var(--pink); font-size: calc(0.8 * var(--sidebar-toggle-size)); diff --git a/compiler-core/templates/documentation_layout.html b/compiler-core/templates/documentation_layout.html index 10b62b75e..16eb6b014 100644 --- a/compiler-core/templates/documentation_layout.html +++ b/compiler-core/templates/documentation_layout.html @@ -219,7 +219,7 @@

Links

Modules

@@ -302,7 +302,7 @@

Modules

}); hljs.highlightAll(); - + diff --git a/compiler-core/templates/gleam@@main.erl b/compiler-core/templates/gleam@@main.erl index 3b24c496d..6cb7c6b66 100644 --- a/compiler-core/templates/gleam@@main.erl +++ b/compiler-core/templates/gleam@@main.erl @@ -1,10 +1,23 @@ -module('{{ application }}@@main'). - -export([run/1]). +-define(red, "\e[31;1m"). +-define(grey, "\e[90m"). +-define(reset_color, "\e[39m"). +-define(reset_all, "\e[0m"). + run(Module) -> io:setopts(standard_io, [binary, {encoding, utf8}]), io:setopts(standard_error, [{encoding, utf8}]), + process_flag(trap_exit, true), + Pid = spawn_link(fun() -> run_module(Module) end), + receive + {'EXIT', Pid, {Reason, StackTrace}} -> + print_error(exit, Reason, StackTrace), + init:stop(1) + end. + +run_module(Module) -> try {ok, _} = application:ensure_all_started('{{ application }}'), erlang:process_flag(trap_exit, false), @@ -13,23 +26,74 @@ run(Module) -> catch Class:Reason:StackTrace -> print_error(Class, Reason, StackTrace), - erlang:halt(127, [{flush, true}]) + init:stop(1) end. -print_error(Class, Reason, StackTrace) -> - E = erl_error:format_exception( - 1, Class, Reason, StackTrace, fun stack_filter/3, - fun print_stack_frame/2, unicode - ), - io:put_chars(E). - -stack_filter(Module, _F, _A) -> - case Module of - ?MODULE -> true; - erl_eval -> true; - init -> true; - _ -> false +print_error(Class, Error, Stacktrace) -> + Printed = [ + ?red, "runtime error: ", ?reset_color, error_class(Class, Error), ?reset_all, + "\n\n", + error_message(Error), + "\n\n", + error_details(Class, Error), + "stacktrace:\n", + [error_frame(Line) || Line <- refine_first(Error, Stacktrace)] + ], + io:format(standard_error, "~ts~n", [Printed]). + +refine_first(#{gleam_error := _, line := L}, [{M, F, A, [{file, Fi} | _]} | S]) -> + [{M, F, A, [{file, Fi}, {line, L}]} | S]; +refine_first(_, S) -> + S. + +error_class(_, #{gleam_error := panic}) -> "panic"; +error_class(_, #{gleam_error := todo}) -> "todo"; +error_class(_, #{gleam_error := let_assert}) -> "let assert"; +error_class(Class, _) -> ["Erlang ", atom_to_binary(Class)]. + +error_message(#{gleam_error := _, message := M}) -> + M; +error_message(undef) -> + <<"A function was called but it did not exist."/utf8 >>; +error_message({case_clause, _}) -> + <<"No pattern matched in an Erlang case expression."/utf8>>; +error_message({badmatch, _}) -> + <<"An Erlang assignment pattern did not match."/utf8>>; +error_message(function_clause) -> + <<"No Erlang function clause matched the arguments it was called with."/utf8>>; +error_message(_) -> + <<"An error occurred outside of Gleam."/utf8>>. + +error_details(_, #{gleam_error := let_assert, value := V}) -> + ["unmatched value:\n ", print_term(V), $\n, $\n]; +error_details(_, {case_clause, V}) -> + ["unmatched value:\n ", print_term(V), $\n, $\n]; +error_details(_, {badmatch, V}) -> + ["unmatched value:\n ", print_term(V), $\n, $\n]; +error_details(_, #{gleam_error := _}) -> + []; +error_details(error, function_clause) -> + []; +error_details(error, undef) -> + []; +error_details(C, E) -> + ["erlang:", atom_to_binary(C), $(, print_term(E), $), $\n, $\n]. + +print_term(T) -> + try + gleam@string:inspect(T) + catch + _:_ -> io_lib:format("~p", [T]) end. -print_stack_frame(Term, I) -> - io_lib:format("~." ++ integer_to_list(I) ++ "tP", [Term, 50]). +error_frame({?MODULE, _, _, _}) -> []; +error_frame({erl_eval, _, _, _}) -> []; +error_frame({init, _, _, _}) -> []; +error_frame({M, F, _, O}) -> + M1 = string:replace(atom_to_binary(M), "@", "/", all), + [" ", M1, $., atom_to_binary(F), error_frame_end(O), $\n]. + +error_frame_end([{file, Fi}, {line, L} | _]) -> + [?grey, $\s, Fi, $:, integer_to_binary(L), ?reset_all]; +error_frame_end(_) -> + [?grey, " unknown source", ?reset_all]. diff --git a/compiler-core/templates/prelude.d.mts b/compiler-core/templates/prelude.d.mts index f6f9aeb14..bb8a9c7d7 100644 --- a/compiler-core/templates/prelude.d.mts +++ b/compiler-core/templates/prelude.d.mts @@ -32,7 +32,7 @@ export class BitArray { isBigEndian: boolean, isSigned: boolean ): number; - binaryFromSlice(state: number, end: number): BitArray; + binaryFromSlice(start: number, end: number): BitArray; sliceAfter(index: number): BitArray; } diff --git a/compiler-core/templates/prelude.mjs b/compiler-core/templates/prelude.mjs index ff9baa715..de9589ab4 100644 --- a/compiler-core/templates/prelude.mjs +++ b/compiler-core/templates/prelude.mjs @@ -45,6 +45,7 @@ export class List { return desired === 0; } + // @internal countLength() { let length = 0; for (let _ of this) length++; @@ -169,24 +170,24 @@ export function sizedInt(value, size, isBigEndian) { // Convert negative number to two's complement representation if (value < 0) { - value = (2 ** size) + value; + value = 2 ** size + value; } if (isBigEndian) { - for (let i = 0; i < byteArray.length; i++) { - const byte = value % 256 + for (let i = byteArray.length - 1; i >= 0; i--) { + const byte = value % 256; byteArray[i] = byte; value = (value - byte) / 256; } } else { - for (let i = byteArray.length - 1; i >= 0; i--) { - const byte = value % 256 + for (let i = 0; i < byteArray.length; i++) { + const byte = value % 256; byteArray[i] = byte; value = (value - byte) / 256; } } - return byteArray.reverse(); + return byteArray; } // @internal @@ -226,9 +227,9 @@ export function byteArrayToFloat(byteArray, start, end, isBigEndian) { const byteSize = end - start; if (byteSize === 8) { - return view.getFloat64(start, !isBigEndian) + return view.getFloat64(start, !isBigEndian); } else if (byteSize === 4) { - return view.getFloat32(start, !isBigEndian) + return view.getFloat32(start, !isBigEndian); } else { const msg = `Sized floats must be 32-bit or 64-bit on JavaScript, got size of ${byteSize * 8} bits`; throw new globalThis.Error(msg); @@ -261,7 +262,7 @@ export function sizedFloat(float, size, isBigEndian) { } else if (size === 32) { view.setFloat32(0, float, !isBigEndian); } - + return byteArray; } @@ -414,6 +415,8 @@ export function makeError(variant, module, line, fn, message, extra) { error.gleam_error = variant; error.module = module; error.line = line; + error.function = fn; + // TODO: Remove this with Gleam v2.0.0 error.fn = fn; for (let k in extra) error[k] = extra[k]; return error; diff --git a/compiler-wasm/src/lib.rs b/compiler-wasm/src/lib.rs index f8a527181..bb01ec7b1 100644 --- a/compiler-wasm/src/lib.rs +++ b/compiler-wasm/src/lib.rs @@ -16,7 +16,7 @@ use glistix_core::{ }; use hexpm::version::Version; use im::HashMap; -use std::{cell::RefCell, collections::HashSet, sync::Arc}; +use std::{cell::RefCell, collections::HashSet, rc::Rc}; use wasm_filesystem::WasmFileSystem; use wasm_bindgen::prelude::*; @@ -182,7 +182,7 @@ fn do_compile_package(project: Project, target: Target) -> Result<(), Error> { let mut type_manifests = im::HashMap::new(); let mut defined_modules = im::HashMap::new(); #[allow(clippy::arc_with_non_send_sync)] - let warning_emitter = WarningEmitter::new(Arc::new(project.warnings)); + let warning_emitter = WarningEmitter::new(Rc::new(project.warnings)); let config = PackageConfig { name: "library".into(), version: Version::new(1, 0, 0), diff --git a/compiler-wasm/src/log_telemetry.rs b/compiler-wasm/src/log_telemetry.rs index b0604b8fb..bb94d5280 100644 --- a/compiler-wasm/src/log_telemetry.rs +++ b/compiler-wasm/src/log_telemetry.rs @@ -3,10 +3,18 @@ use glistix_core::build::Telemetry; pub struct LogTelemetry; impl Telemetry for LogTelemetry { + fn compiled_package(&self, duration: std::time::Duration) { + tracing::info!("Compiled in {} ", seconds(duration)); + } + fn compiling_package(&self, name: &str) { tracing::info!("Compiling package: {}", name); } + fn checked_package(&self, duration: std::time::Duration) { + tracing::info!("Checked in {}", seconds(duration)); + } + fn checking_package(&self, name: &str) { tracing::info!("Checking package: {}", name); } @@ -15,6 +23,10 @@ impl Telemetry for LogTelemetry { tracing::info!("Downloading package: {}", name); } + fn running(&self, name: &str) { + tracing::info!("Running {}", name); + } + fn resolving_package_versions(&self) { tracing::info!("Resolving package versions"); } @@ -27,3 +39,7 @@ impl Telemetry for LogTelemetry { tracing::info!("Waiting for build directory lock"); } } + +pub fn seconds(duration: std::time::Duration) -> String { + format!("{:.2}s", duration.as_millis() as f32 / 1000.) +} diff --git a/docs/runtime-errors.md b/docs/runtime-errors.md new file mode 100644 index 000000000..45ef353ce --- /dev/null +++ b/docs/runtime-errors.md @@ -0,0 +1,67 @@ +# Runtime errors + +There are several runtime errors that Gleam code can throw. This documentation +lists them and their runtime properties. + +On Erlang runtime errors are Erlang maps thrown with `erlang:error/1`, having at +least these properties: + +| Key | Type | Value | +| --- | ---- | ----- | +| gleam_error | Atom | See individual errors | +| message | String | See individual errors | +| module | String | The module the error occured in | +| function | String | The function the error occured in | +| line | Int | The line number the error occured on | + +On JavaScript runtime errors are instances of the JavaScript `Error` class, +having at least these properties added to them: + +| Key | Type | Value | +| --- | ---- | ----- | +| gleam_error | String | See individual errors | +| message | String | See individual errors | +| module | String | The module the error occured in | +| function | String | The function the error occured in | +| line | Number | The line number the error occured on | + +## Todo + +A panic that indicates that the code has not yet been completed, intended for +use in development. + +```gleam +todo +todo as "some message" +``` +| Key | Erlang Value | JavaScript Value | +| --- | ------------ | ---------------- | +| gleam_error | `todo` | `"todo"` | +| message | The given message | The given message | + +## Panic + +An explicit panic to unconditionally error. + +```gleam +panic +panic as "some message" +``` +| Key | Erlang Value | JavaScript Value | +| --- | ------------ | ---------------- | +| gleam_error | `panic` | `"panic"` | +| message | The given message | The given message | + +## Let assert + +An inexhaustive pattern match, erroring if the pattern does not match. + +```gleam +let assert Ok(x) = something() + +``` +| Key | Erlang Value | JavaScript Value | +| --- | ------------ | ---------------- | +| gleam_error | `let_assert` | `"let_assert"` | +| message | The given message | The given message | +| value | The unmatched value | The unmatched value | diff --git a/nix/glistix.nix b/nix/glistix.nix index 55b1ddee1..01fc6163d 100644 --- a/nix/glistix.nix +++ b/nix/glistix.nix @@ -39,7 +39,7 @@ rustPlatform.buildRustPackage { buildInputs = [ openssl ] ++ lib.optionals stdenv.isDarwin [ Security SystemConfiguration ]; - cargoHash = "sha256-LLeJyOlAe+uAGNBX8Vq+qiSUXE61VhoecibhtWsdaNA="; + cargoHash = "sha256-zzspempE5quAhsx0XHQAm3NQ02zJyKWCQiYdlCByvRs="; meta = with lib; { description = "A fork of the Gleam compiler with a Nix backend"; diff --git a/test-package-compiler/build.rs b/test-package-compiler/build.rs index ef969ecc3..c45590a9b 100644 --- a/test-package-compiler/build.rs +++ b/test-package-compiler/build.rs @@ -15,7 +15,8 @@ pub fn main() { .map(|entry| entry.unwrap().file_name().into_string().unwrap()) .collect(); names.sort(); - for name in names.into_iter() { + + for name in names { let path = cases.join(&name); let path = path.to_str().unwrap().replace('\\', "/"); module.push_str(&format!( @@ -23,12 +24,11 @@ pub fn main() { #[rustfmt::skip] #[test] fn {name}() {{ - let output = - crate::prepare("{path}"); + let output = crate::prepare("{path}"); insta::assert_snapshot!( "{name}", output, - "{path}" + "{path}", ); }} "# diff --git a/test-package-compiler/src/generated_tests.rs b/test-package-compiler/src/generated_tests.rs index aefea2a1f..6e8ebe876 100644 --- a/test-package-compiler/src/generated_tests.rs +++ b/test-package-compiler/src/generated_tests.rs @@ -4,347 +4,318 @@ #[rustfmt::skip] #[test] fn alias_unqualified_import() { - let output = - crate::prepare("./cases/alias_unqualified_import"); + let output = crate::prepare("./cases/alias_unqualified_import"); insta::assert_snapshot!( "alias_unqualified_import", output, - "./cases/alias_unqualified_import" + "./cases/alias_unqualified_import", ); } #[rustfmt::skip] #[test] fn duplicate_module() { - let output = - crate::prepare("./cases/duplicate_module"); + let output = crate::prepare("./cases/duplicate_module"); insta::assert_snapshot!( "duplicate_module", output, - "./cases/duplicate_module" + "./cases/duplicate_module", ); } #[rustfmt::skip] #[test] fn erlang_app_generation() { - let output = - crate::prepare("./cases/erlang_app_generation"); + let output = crate::prepare("./cases/erlang_app_generation"); insta::assert_snapshot!( "erlang_app_generation", output, - "./cases/erlang_app_generation" + "./cases/erlang_app_generation", ); } #[rustfmt::skip] #[test] fn erlang_bug_752() { - let output = - crate::prepare("./cases/erlang_bug_752"); + let output = crate::prepare("./cases/erlang_bug_752"); insta::assert_snapshot!( "erlang_bug_752", output, - "./cases/erlang_bug_752" + "./cases/erlang_bug_752", ); } #[rustfmt::skip] #[test] fn erlang_empty() { - let output = - crate::prepare("./cases/erlang_empty"); + let output = crate::prepare("./cases/erlang_empty"); insta::assert_snapshot!( "erlang_empty", output, - "./cases/erlang_empty" + "./cases/erlang_empty", ); } #[rustfmt::skip] #[test] fn erlang_escape_names() { - let output = - crate::prepare("./cases/erlang_escape_names"); + let output = crate::prepare("./cases/erlang_escape_names"); insta::assert_snapshot!( "erlang_escape_names", output, - "./cases/erlang_escape_names" + "./cases/erlang_escape_names", ); } #[rustfmt::skip] #[test] fn erlang_import() { - let output = - crate::prepare("./cases/erlang_import"); + let output = crate::prepare("./cases/erlang_import"); insta::assert_snapshot!( "erlang_import", output, - "./cases/erlang_import" + "./cases/erlang_import", ); } #[rustfmt::skip] #[test] fn erlang_import_shadowing_prelude() { - let output = - crate::prepare("./cases/erlang_import_shadowing_prelude"); + let output = crate::prepare("./cases/erlang_import_shadowing_prelude"); insta::assert_snapshot!( "erlang_import_shadowing_prelude", output, - "./cases/erlang_import_shadowing_prelude" + "./cases/erlang_import_shadowing_prelude", ); } #[rustfmt::skip] #[test] fn erlang_nested() { - let output = - crate::prepare("./cases/erlang_nested"); + let output = crate::prepare("./cases/erlang_nested"); insta::assert_snapshot!( "erlang_nested", output, - "./cases/erlang_nested" + "./cases/erlang_nested", ); } #[rustfmt::skip] #[test] fn erlang_nested_qualified_constant() { - let output = - crate::prepare("./cases/erlang_nested_qualified_constant"); + let output = crate::prepare("./cases/erlang_nested_qualified_constant"); insta::assert_snapshot!( "erlang_nested_qualified_constant", output, - "./cases/erlang_nested_qualified_constant" + "./cases/erlang_nested_qualified_constant", ); } #[rustfmt::skip] #[test] fn hello_joe() { - let output = - crate::prepare("./cases/hello_joe"); + let output = crate::prepare("./cases/hello_joe"); insta::assert_snapshot!( "hello_joe", output, - "./cases/hello_joe" + "./cases/hello_joe", ); } #[rustfmt::skip] #[test] fn import_cycle() { - let output = - crate::prepare("./cases/import_cycle"); + let output = crate::prepare("./cases/import_cycle"); insta::assert_snapshot!( "import_cycle", output, - "./cases/import_cycle" + "./cases/import_cycle", ); } #[rustfmt::skip] #[test] fn import_cycle_multi() { - let output = - crate::prepare("./cases/import_cycle_multi"); + let output = crate::prepare("./cases/import_cycle_multi"); insta::assert_snapshot!( "import_cycle_multi", output, - "./cases/import_cycle_multi" + "./cases/import_cycle_multi", ); } #[rustfmt::skip] #[test] fn import_shadowed_name_warning() { - let output = - crate::prepare("./cases/import_shadowed_name_warning"); + let output = crate::prepare("./cases/import_shadowed_name_warning"); insta::assert_snapshot!( "import_shadowed_name_warning", output, - "./cases/import_shadowed_name_warning" + "./cases/import_shadowed_name_warning", ); } #[rustfmt::skip] #[test] fn imported_constants() { - let output = - crate::prepare("./cases/imported_constants"); + let output = crate::prepare("./cases/imported_constants"); insta::assert_snapshot!( "imported_constants", output, - "./cases/imported_constants" + "./cases/imported_constants", ); } #[rustfmt::skip] #[test] fn imported_external_fns() { - let output = - crate::prepare("./cases/imported_external_fns"); + let output = crate::prepare("./cases/imported_external_fns"); insta::assert_snapshot!( "imported_external_fns", output, - "./cases/imported_external_fns" + "./cases/imported_external_fns", ); } #[rustfmt::skip] #[test] fn imported_record_constructors() { - let output = - crate::prepare("./cases/imported_record_constructors"); + let output = crate::prepare("./cases/imported_record_constructors"); insta::assert_snapshot!( "imported_record_constructors", output, - "./cases/imported_record_constructors" + "./cases/imported_record_constructors", ); } #[rustfmt::skip] #[test] fn javascript_d_ts() { - let output = - crate::prepare("./cases/javascript_d_ts"); + let output = crate::prepare("./cases/javascript_d_ts"); insta::assert_snapshot!( "javascript_d_ts", output, - "./cases/javascript_d_ts" + "./cases/javascript_d_ts", ); } #[rustfmt::skip] #[test] fn javascript_empty() { - let output = - crate::prepare("./cases/javascript_empty"); + let output = crate::prepare("./cases/javascript_empty"); insta::assert_snapshot!( "javascript_empty", output, - "./cases/javascript_empty" + "./cases/javascript_empty", ); } #[rustfmt::skip] #[test] fn javascript_import() { - let output = - crate::prepare("./cases/javascript_import"); + let output = crate::prepare("./cases/javascript_import"); insta::assert_snapshot!( "javascript_import", output, - "./cases/javascript_import" + "./cases/javascript_import", ); } #[rustfmt::skip] #[test] fn not_overwriting_erlang_module() { - let output = - crate::prepare("./cases/not_overwriting_erlang_module"); + let output = crate::prepare("./cases/not_overwriting_erlang_module"); insta::assert_snapshot!( "not_overwriting_erlang_module", output, - "./cases/not_overwriting_erlang_module" + "./cases/not_overwriting_erlang_module", ); } #[rustfmt::skip] #[test] fn opaque_type_accessor() { - let output = - crate::prepare("./cases/opaque_type_accessor"); + let output = crate::prepare("./cases/opaque_type_accessor"); insta::assert_snapshot!( "opaque_type_accessor", output, - "./cases/opaque_type_accessor" + "./cases/opaque_type_accessor", ); } #[rustfmt::skip] #[test] fn opaque_type_destructure() { - let output = - crate::prepare("./cases/opaque_type_destructure"); + let output = crate::prepare("./cases/opaque_type_destructure"); insta::assert_snapshot!( "opaque_type_destructure", output, - "./cases/opaque_type_destructure" + "./cases/opaque_type_destructure", ); } #[rustfmt::skip] #[test] fn overwriting_erlang_module() { - let output = - crate::prepare("./cases/overwriting_erlang_module"); + let output = crate::prepare("./cases/overwriting_erlang_module"); insta::assert_snapshot!( "overwriting_erlang_module", output, - "./cases/overwriting_erlang_module" + "./cases/overwriting_erlang_module", ); } #[rustfmt::skip] #[test] fn src_importing_test() { - let output = - crate::prepare("./cases/src_importing_test"); + let output = crate::prepare("./cases/src_importing_test"); insta::assert_snapshot!( "src_importing_test", output, - "./cases/src_importing_test" + "./cases/src_importing_test", ); } #[rustfmt::skip] #[test] fn unknown_module_field_in_constant() { - let output = - crate::prepare("./cases/unknown_module_field_in_constant"); + let output = crate::prepare("./cases/unknown_module_field_in_constant"); insta::assert_snapshot!( "unknown_module_field_in_constant", output, - "./cases/unknown_module_field_in_constant" + "./cases/unknown_module_field_in_constant", ); } #[rustfmt::skip] #[test] fn unknown_module_field_in_expression() { - let output = - crate::prepare("./cases/unknown_module_field_in_expression"); + let output = crate::prepare("./cases/unknown_module_field_in_expression"); insta::assert_snapshot!( "unknown_module_field_in_expression", output, - "./cases/unknown_module_field_in_expression" + "./cases/unknown_module_field_in_expression", ); } #[rustfmt::skip] #[test] fn unknown_module_field_in_import() { - let output = - crate::prepare("./cases/unknown_module_field_in_import"); + let output = crate::prepare("./cases/unknown_module_field_in_import"); insta::assert_snapshot!( "unknown_module_field_in_import", output, - "./cases/unknown_module_field_in_import" + "./cases/unknown_module_field_in_import", ); } #[rustfmt::skip] #[test] fn variable_or_module() { - let output = - crate::prepare("./cases/variable_or_module"); + let output = crate::prepare("./cases/variable_or_module"); insta::assert_snapshot!( "variable_or_module", output, - "./cases/variable_or_module" + "./cases/variable_or_module", ); } diff --git a/test-package-compiler/src/lib.rs b/test-package-compiler/src/lib.rs index 2565038f6..dbd3560ea 100644 --- a/test-package-compiler/src/lib.rs +++ b/test-package-compiler/src/lib.rs @@ -21,7 +21,8 @@ use regex::Regex; use std::{ collections::{HashMap, HashSet}, fmt::Write, - sync::Arc, + rc::Rc, + sync::OnceLock, }; use camino::{Utf8Path, Utf8PathBuf}; @@ -51,7 +52,7 @@ pub fn prepare(path: &str) -> String { let ids = glistix_core::uid::UniqueIdGenerator::new(); let mut modules = im::HashMap::new(); let warnings = VectorWarningEmitterIO::default(); - let warning_emitter = WarningEmitter::new(Arc::new(warnings.clone())); + let warning_emitter = WarningEmitter::new(Rc::new(warnings.clone())); let filesystem = to_in_memory_filesystem(&root); let initial_files = filesystem.paths(); let root = Utf8PathBuf::from(""); @@ -106,6 +107,8 @@ fn normalise_diagnostic(text: &str) -> String { .replace('\\', "/") } +static FILE_LINE_REGEX: OnceLock = OnceLock::new(); + #[derive(Debug)] pub struct TestCompileOutput { files: HashMap, @@ -116,15 +119,27 @@ impl TestCompileOutput { pub fn as_overview_text(&self) -> String { let mut buffer = String::new(); for (path, content) in self.files.iter().sorted_by(|a, b| a.0.cmp(b.0)) { + let normalised_path = path.as_str().replace('\\', "/"); buffer.push_str("//// "); - buffer.push_str(&path.as_str().replace('\\', "/")); + buffer.push_str(&normalised_path); buffer.push('\n'); let extension = path.extension(); match content { _ if extension == Some("cache") => buffer.push_str("<.cache binary>"), Content::Binary(data) => write!(buffer, "<{} byte binary>", data.len()).unwrap(), - Content::Text(text) => buffer.push_str(text), + Content::Text(text) => { + let text = FILE_LINE_REGEX + .get_or_init(|| { + Regex::new(r#"-file\("([^"]+)", (\d+)\)\."#).expect("Invalid regex") + }) + .replace_all(text, |caps: ®ex::Captures| { + let path = caps.get(1).expect("file path").as_str().replace("\\", "/"); + let line_number = caps.get(2).expect("line number").as_str(); + format!("-file(\"{}\", {}).", path, line_number) + }); + buffer.push_str(&text) + } }; buffer.push('\n'); buffer.push('\n'); diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__alias_unqualified_import.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__alias_unqualified_import.snap index 875434e91..fdcb22afa 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__alias_unqualified_import.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__alias_unqualified_import.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 8 expression: "./cases/alias_unqualified_import" --- //// /out/lib/the_package/_gleam_artefacts/one.cache @@ -17,6 +18,7 @@ expression: "./cases/alias_unqualified_import" -type empty() :: empty. +-file("src/one.gleam", 2). -spec id(I) -> I. id(X) -> X. @@ -34,6 +36,7 @@ id(X) -> -export([make/0]). +-file("src/two.gleam", 4). -spec make() -> one:empty(). make() -> one:id(empty). diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_escape_names.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_escape_names.snap index 16c218ce9..8ec302b78 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_escape_names.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_escape_names.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 63 expression: "./cases/erlang_escape_names" --- //// /out/lib/the_package/_gleam_artefacts/one.cache @@ -14,6 +15,7 @@ expression: "./cases/erlang_escape_names" -export(['receive'/1]). +-file("src/one.gleam", 2). -spec 'receive'(I) -> I. 'receive'(X) -> X. @@ -31,18 +33,22 @@ expression: "./cases/erlang_escape_names" -export([qualified_call/0, qualified_value/0, unqualified_call/0, unqualified_value/0]). +-file("src/two.gleam", 4). -spec qualified_call() -> integer(). qualified_call() -> one:'receive'(1). +-file("src/two.gleam", 8). -spec qualified_value() -> fun((Q) -> Q). qualified_value() -> fun one:'receive'/1. +-file("src/two.gleam", 12). -spec unqualified_call() -> integer(). unqualified_call() -> one:'receive'(1). +-file("src/two.gleam", 16). -spec unqualified_value() -> fun((S) -> S). unqualified_value() -> fun one:'receive'/1. diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_import.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_import.snap index b23c8694b..92a86d91f 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_import.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_import.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 74 expression: "./cases/erlang_import" --- //// /out/lib/the_package/_gleam_artefacts/one.cache @@ -14,6 +15,7 @@ expression: "./cases/erlang_import" -export([unbox/1]). +-file("src/one.gleam", 3). -spec unbox(two:box()) -> integer(). unbox(X) -> {box, I} = X, diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_import_shadowing_prelude.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_import_shadowing_prelude.snap index 0a512a6ed..ee8b537bf 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_import_shadowing_prelude.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_import_shadowing_prelude.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 85 expression: "./cases/erlang_import_shadowing_prelude" --- //// /out/lib/the_package/_gleam_artefacts/one.cache @@ -31,6 +32,7 @@ expression: "./cases/erlang_import_shadowing_prelude" -export([main/0]). +-file("src/two.gleam", 4). -spec main() -> one:error(). main() -> error. diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_nested.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_nested.snap index ad9cc9985..2e4120d7d 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_nested.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__erlang_nested.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 96 expression: "./cases/erlang_nested" --- //// /out/lib/the_package/_gleam_artefacts/one@two.cache @@ -14,6 +15,7 @@ expression: "./cases/erlang_nested" -export([main/0]). +-file("src/one/two.gleam", 1). -spec main() -> binary(). main() -> <<"Hi there"/utf8>>. diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__hello_joe.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__hello_joe.snap index a32caf730..b083da9fc 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__hello_joe.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__hello_joe.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 118 expression: "./cases/hello_joe" --- //// /out/lib/the_package/_gleam_artefacts/hello_joe.cache @@ -14,6 +15,7 @@ expression: "./cases/hello_joe" -export([main/0]). +-file("src/hello_joe.gleam", 1). -spec main() -> binary(). main() -> <<"Hello, Joe!"/utf8>>. diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__import_shadowed_name_warning.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__import_shadowed_name_warning.snap index aee8a906d..d11b9f3c9 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__import_shadowed_name_warning.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__import_shadowed_name_warning.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 151 expression: "./cases/import_shadowed_name_warning" --- //// /out/lib/the_package/_gleam_artefacts/one.cache @@ -34,6 +35,7 @@ expression: "./cases/import_shadowed_name_warning" -type shadowing() :: port. +-file("src/two.gleam", 14). -spec use_type(one:port_()) -> nil. use_type(Port) -> wibble:wobble(Port). @@ -51,7 +53,6 @@ use_type(Port) -> //// Warning - warning: Unused private constructor ┌─ src/two.gleam:9:3 │ @@ -61,8 +62,8 @@ warning: Unused private constructor Hint: You can safely remove it. -//// Warning +//// Warning warning: Unused private type ┌─ src/two.gleam:7:1 │ diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_constants.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_constants.snap index 9bdb84324..7e7558517 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_constants.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_constants.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 162 expression: "./cases/imported_constants" --- //// /out/lib/the_package/_gleam_artefacts/one.cache @@ -35,47 +36,57 @@ expression: "./cases/imported_constants" -export([accessors/1, destructure_qualified/1, destructure_unqualified/1, destructure_aliased/1, qualified_fn_a/0, qualified_fn_b/0, unqualified_fn_a/0, unqualified_fn_b/0, aliased_fn_a/0, aliased_fn_b/0]). +-file("src/two.gleam", 45). -spec accessors(one:user()) -> {binary(), integer()}. accessors(User) -> Name = erlang:element(2, User), Score = erlang:element(3, User), {Name, Score}. +-file("src/two.gleam", 52). -spec destructure_qualified(one:user()) -> {binary(), integer()}. destructure_qualified(User) -> {user, Name, Score} = User, {Name, Score}. +-file("src/two.gleam", 57). -spec destructure_unqualified(one:user()) -> {binary(), integer()}. destructure_unqualified(User) -> {user, Name, Score} = User, {Name, Score}. +-file("src/two.gleam", 62). -spec destructure_aliased(one:user()) -> {binary(), integer()}. destructure_aliased(User) -> {user, Name, Score} = User, {Name, Score}. +-file("src/two.gleam", 6). -spec qualified_fn_a() -> one:a(). qualified_fn_a() -> a. +-file("src/two.gleam", 12). -spec qualified_fn_b() -> one:b(). qualified_fn_b() -> {b, a, a}. +-file("src/two.gleam", 19). -spec unqualified_fn_a() -> one:a(). unqualified_fn_a() -> a. +-file("src/two.gleam", 25). -spec unqualified_fn_b() -> one:b(). unqualified_fn_b() -> {b, a, a}. +-file("src/two.gleam", 33). -spec aliased_fn_a() -> one:a(). aliased_fn_a() -> a. +-file("src/two.gleam", 39). -spec aliased_fn_b() -> one:b(). aliased_fn_b() -> {b, a, a}. diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_external_fns.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_external_fns.snap index 3e0f7a2a7..addd2e3dc 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_external_fns.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_external_fns.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 173 expression: "./cases/imported_external_fns" --- //// /out/lib/the_package/_gleam_artefacts/one.cache @@ -14,6 +15,7 @@ expression: "./cases/imported_external_fns" -export([thing/0]). +-file("src/one.gleam", 2). -spec thing() -> nil. thing() -> thing:new(). @@ -31,38 +33,47 @@ thing() -> -export([fn_reference_qualified/0, fn_reference_qualified_aliased/0, fn_reference_unqualified/0, fn_reference_unqualified_aliased/0, fn_call_qualified/0, fn_call_qualified_aliased/0, fn_call_unqualified/0, fn_call_unqualified_aliased/0, the_consts/0]). +-file("src/two.gleam", 27). -spec fn_reference_qualified() -> fun(() -> nil). fn_reference_qualified() -> fun thing:new/0. +-file("src/two.gleam", 31). -spec fn_reference_qualified_aliased() -> fun(() -> nil). fn_reference_qualified_aliased() -> fun thing:new/0. +-file("src/two.gleam", 35). -spec fn_reference_unqualified() -> fun(() -> nil). fn_reference_unqualified() -> fun thing:new/0. +-file("src/two.gleam", 39). -spec fn_reference_unqualified_aliased() -> fun(() -> nil). fn_reference_unqualified_aliased() -> fun thing:new/0. +-file("src/two.gleam", 45). -spec fn_call_qualified() -> nil. fn_call_qualified() -> thing:new(). +-file("src/two.gleam", 49). -spec fn_call_qualified_aliased() -> nil. fn_call_qualified_aliased() -> thing:new(). +-file("src/two.gleam", 53). -spec fn_call_unqualified() -> nil. fn_call_unqualified() -> thing:new(). +-file("src/two.gleam", 57). -spec fn_call_unqualified_aliased() -> nil. fn_call_unqualified_aliased() -> thing:new(). +-file("src/two.gleam", 14). -spec the_consts() -> nil. the_consts() -> _ = fun thing:new/0, diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_record_constructors.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_record_constructors.snap index 70c118f08..b78b38fdd 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_record_constructors.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__imported_record_constructors.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 184 expression: "./cases/imported_record_constructors" --- //// /out/lib/the_package/_gleam_artefacts/one@one.cache @@ -35,76 +36,93 @@ expression: "./cases/imported_record_constructors" -export([accessors/1, destructure_qualified/1, destructure_qualified_aliased/1, destructure_unqualified/1, destructure_aliased/1, update_qualified/1, update_qualified_aliased/1, update_unqualified/1, update_aliased/1, qualified_fn_a/0, qualified_fn_b/0, qualified_aliased_fn_a/0, qualified_aliased_fn_b/0, unqualified_fn_a/0, unqualified_fn_b/0, aliased_fn_a/0, aliased_fn_b/0]). +-file("src/two.gleam", 58). -spec accessors(one@one:user()) -> {binary(), integer()}. accessors(User) -> Name = erlang:element(2, User), Score = erlang:element(3, User), {Name, Score}. +-file("src/two.gleam", 65). -spec destructure_qualified(one@one:user()) -> {binary(), integer()}. destructure_qualified(User) -> {user, Name, Score} = User, {Name, Score}. +-file("src/two.gleam", 70). -spec destructure_qualified_aliased(one@one:user()) -> {binary(), integer()}. destructure_qualified_aliased(User) -> {user, Name, Score} = User, {Name, Score}. +-file("src/two.gleam", 75). -spec destructure_unqualified(one@one:user()) -> {binary(), integer()}. destructure_unqualified(User) -> {user, Name, Score} = User, {Name, Score}. +-file("src/two.gleam", 80). -spec destructure_aliased(one@one:user()) -> {binary(), integer()}. destructure_aliased(User) -> {user, Name, Score} = User, {Name, Score}. +-file("src/two.gleam", 86). -spec update_qualified(one@one:user()) -> one@one:user(). update_qualified(User) -> erlang:setelement(2, User, <<"wibble"/utf8>>). +-file("src/two.gleam", 90). -spec update_qualified_aliased(one@one:user()) -> one@one:user(). update_qualified_aliased(User) -> erlang:setelement(2, User, <<"wibble"/utf8>>). +-file("src/two.gleam", 94). -spec update_unqualified(one@one:user()) -> one@one:user(). update_unqualified(User) -> erlang:setelement(2, User, <<"wibble"/utf8>>). +-file("src/two.gleam", 98). -spec update_aliased(one@one:user()) -> one@one:user(). update_aliased(User) -> erlang:setelement(2, User, <<"wibble"/utf8>>). +-file("src/two.gleam", 7). -spec qualified_fn_a() -> one@one:a(). qualified_fn_a() -> a. +-file("src/two.gleam", 13). -spec qualified_fn_b() -> one@one:b(). qualified_fn_b() -> {b, a, a}. +-file("src/two.gleam", 19). -spec qualified_aliased_fn_a() -> one@one:a(). qualified_aliased_fn_a() -> a. +-file("src/two.gleam", 25). -spec qualified_aliased_fn_b() -> one@one:b(). qualified_aliased_fn_b() -> {b, a, a}. +-file("src/two.gleam", 32). -spec unqualified_fn_a() -> one@one:a(). unqualified_fn_a() -> a. +-file("src/two.gleam", 38). -spec unqualified_fn_b() -> one@one:b(). unqualified_fn_b() -> {b, a, a}. +-file("src/two.gleam", 46). -spec aliased_fn_a() -> one@one:a(). aliased_fn_a() -> a. +-file("src/two.gleam", 52). -spec aliased_fn_b() -> one@one:b(). aliased_fn_b() -> {b, a, a}. diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__opaque_type_destructure.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__opaque_type_destructure.snap index a52beba6c..dc9e0ce01 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__opaque_type_destructure.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__opaque_type_destructure.snap @@ -2,7 +2,7 @@ source: test-package-compiler/src/generated_tests.rs expression: "./cases/opaque_type_destructure" --- -error: Unknown module field +error: Unknown module value ┌─ src/two.gleam:7:7 │ 7 │ let one.User(name: name, score: score) = user diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_constant.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_constant.snap index 6602ffd28..aa1970b3b 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_constant.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_constant.snap @@ -1,13 +1,11 @@ --- source: test-package-compiler/src/generated_tests.rs -assertion_line: 285 expression: "./cases/unknown_module_field_in_constant" --- -error: Unknown module field +error: Unknown module value ┌─ src/two.gleam:3:16 │ 3 │ pub const it = one.B │ ^ Did you mean `A`? The module `one` does not have a `B` value. - diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_expression.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_expression.snap index 7dfea806b..8017e62b0 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_expression.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_expression.snap @@ -1,13 +1,11 @@ --- source: test-package-compiler/src/generated_tests.rs -assertion_line: 297 expression: "./cases/unknown_module_field_in_expression" --- -error: Unknown module field +error: Unknown module value ┌─ src/two.gleam:4:6 │ 4 │ one.B │ ^ Did you mean `A`? The module `one` does not have a `B` value. - diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_import.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_import.snap index 53feb6fb6..bc5821f50 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_import.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__unknown_module_field_in_import.snap @@ -1,13 +1,11 @@ --- source: test-package-compiler/src/generated_tests.rs -assertion_line: 309 expression: "./cases/unknown_module_field_in_import" --- -error: Unknown module field +error: Unknown module value ┌─ src/two.gleam:1:13 │ 1 │ import one.{B} │ ^ Did you mean `A`? The module `one` does not have a `B` value. - diff --git a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__variable_or_module.snap b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__variable_or_module.snap index 9df63e3f7..4613c8e03 100644 --- a/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__variable_or_module.snap +++ b/test-package-compiler/src/snapshots/test_package_compiler__generated_tests__variable_or_module.snap @@ -1,5 +1,6 @@ --- source: test-package-compiler/src/generated_tests.rs +assertion_line: 316 expression: "./cases/variable_or_module" --- //// /out/lib/the_package/_gleam_artefacts/main.cache @@ -14,10 +15,12 @@ expression: "./cases/variable_or_module" -export([module_function/1, record_field/1]). +-file("src/main.gleam", 4). -spec module_function(power:power()) -> integer(). module_function(Power) -> power:to_int(Power). +-file("src/main.gleam", 10). -spec record_field(power:power()) -> integer(). record_field(Power) -> erlang:element(2, Power). @@ -38,6 +41,7 @@ record_field(Power) -> -type power() :: {power, integer()}. +-file("src/power.gleam", 6). -spec to_int(power()) -> integer(). to_int(P) -> erlang:element(2, P) * 9000. diff --git a/test/external_only_erlang/src/external_only_erlang.gleam b/test/external_only_erlang/src/external_only_erlang.gleam index 17bbfcee4..b21f69916 100644 --- a/test/external_only_erlang/src/external_only_erlang.gleam +++ b/test/external_only_erlang/src/external_only_erlang.gleam @@ -1,13 +1,5 @@ // This function is only implemented for Erlang, so if we try and call it from // JavaScript, or build this package for JavaScript, then the compiler will // (should) emit an error. -pub fn main() -> Nil { - run() -} - -// TODO: replace this with the `main` function being an external. -// Currently there is a bug in the compiler's target detection that causes -// functions with no body to not emit an error if they don't support the -// current target. @external(erlang, "external_only_erlang_ffi", "main") -pub fn run() -> Nil +pub fn main() -> Nil diff --git a/test/external_only_javascript/src/external_only_javascript.gleam b/test/external_only_javascript/src/external_only_javascript.gleam index 3f397b852..d7c42c9f1 100644 --- a/test/external_only_javascript/src/external_only_javascript.gleam +++ b/test/external_only_javascript/src/external_only_javascript.gleam @@ -1,13 +1,5 @@ // This function is only implemented for JavaScript, so if we try and call it // from Erlang, or build this package for Erlang, then the compiler will // (should) emit an error. -pub fn main() -> Nil { - run() -} - -// TODO: replace this with the `main` function being an external. -// Currently there is a bug in the compiler's target detection that causes -// functions with no body to not emit an error if they don't support the -// current target. @external(javascript, "./external_only_javascript_ffi.mjs", "main") -pub fn run() -> Nil +pub fn main() -> Nil diff --git a/test/project_erlang/gleam.toml b/test/project_erlang/gleam.toml index a87d540b5..5ba64b93a 100644 --- a/test/project_erlang/gleam.toml +++ b/test/project_erlang/gleam.toml @@ -23,6 +23,9 @@ ssl_verify_fun = "~> 1.1" # TODO: replace this with a package with a nif that compiles super fast. Perhaps # just a hello world. bcrypt = "~> 1.1" +# This is a rebar3 dep that output files in $REBAR_BARE_COMPILER_OUTPUT_DIR/priv +# and requires absolute paths +ezstd = "~> 1.1" # This is a rebar3 dep where the application name (hpack, used by the BEAM) # doesn't match the package name (hpack_erl, used by Hex). diff --git a/test/project_erlang/manifest.toml b/test/project_erlang/manifest.toml index 853fc3eb7..73cb4ba70 100644 --- a/test/project_erlang/manifest.toml +++ b/test/project_erlang/manifest.toml @@ -7,6 +7,7 @@ packages = [ { name = "countries", version = "1.6.0", build_tools = ["mix"], requirements = ["yamerl"], otp_app = "countries", source = "hex", outer_checksum = "A1E4D0FDD2A799F16A95AE2E842EDEAABD9AC7639624AC5E139C54DA7A6BCCB0" }, { name = "cowboy", version = "2.10.0", build_tools = ["make", "rebar3"], requirements = ["cowlib", "ranch"], otp_app = "cowboy", source = "hex", outer_checksum = "3AFDCCB7183CC6F143CB14D3CF51FA00E53DB9EC80CDCD525482F5E99BC41D6B" }, { name = "cowlib", version = "2.12.1", build_tools = ["make", "rebar3"], requirements = [], otp_app = "cowlib", source = "hex", outer_checksum = "163B73F6367A7341B33C794C4E88E7DBFE6498AC42DCD69EF44C5BC5507C8DB0" }, + { name = "ezstd", version = "1.1.0", build_tools = ["rebar3"], requirements = [], otp_app = "ezstd", source = "hex", outer_checksum = "28CFA0ED6CC3922095AD5BA0F23392A1664273358B17184BAA909868361184E7" }, { name = "gleam_erlang", version = "0.24.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "26BDB52E61889F56A291CB34167315780EE4AA20961917314446542C90D1C1A0" }, { name = "gleam_javascript", version = "0.7.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_javascript", source = "hex", outer_checksum = "EEA30D1ABF62B06FC378764D598DF041303CFA33A6586BFF4C4BFEFFA83DBDBE" }, { name = "gleam_stdlib", version = "0.34.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1FB8454D2991E9B4C0C804544D8A9AD0F6184725E20D63C3155F0AEB4230B016" }, @@ -23,6 +24,7 @@ bcrypt = { version = "~> 1.1" } certifi = { version = "~> 2.8" } countries = { version = "~> 1.6" } cowboy = { version = "~> 2.9" } +ezstd = { version = "~> 1.1" } gleam_erlang = { version = "~> 0.5" } gleam_javascript = { version = "~> 0.7" } gleam_stdlib = { version = "~> 0.18" } diff --git a/test/root_package_not_compiled_when_running_dep/.gitignore b/test/root_package_not_compiled_when_running_dep/.gitignore new file mode 100644 index 000000000..599be4eb9 --- /dev/null +++ b/test/root_package_not_compiled_when_running_dep/.gitignore @@ -0,0 +1,4 @@ +*.beam +*.ez +/build +erl_crash.dump diff --git a/test/root_package_not_compiled_when_running_dep/README.md b/test/root_package_not_compiled_when_running_dep/README.md new file mode 100644 index 000000000..a16bdb8ba --- /dev/null +++ b/test/root_package_not_compiled_when_running_dep/README.md @@ -0,0 +1,7 @@ +# root_package_not_compiled_when_running_dep + +This package is used to check that the compiler can compile and run a dependency +even if the root package has compilation errors. + +So one can do `gleam run -m ` even if their own code doesn't +compile. diff --git a/test/root_package_not_compiled_when_running_dep/gleam.toml b/test/root_package_not_compiled_when_running_dep/gleam.toml new file mode 100644 index 000000000..820bbb9b4 --- /dev/null +++ b/test/root_package_not_compiled_when_running_dep/gleam.toml @@ -0,0 +1,20 @@ +name = "root_package_not_compiled_when_running_dep" +version = "1.0.0" + +# Fill out these fields if you intend to generate HTML documentation or publish +# your project to the Hex package manager. +# +# description = "" +# licences = ["Apache-2.0"] +# repository = { type = "github", user = "", repo = "" } +# links = [{ title = "Website", href = "" }] +# +# For a full reference of all the available options, you can have a look at +# https://gleam.run/writing-gleam/gleam-toml/. + +[dependencies] +gleam_stdlib = ">= 0.34.0 and < 2.0.0" +hello_joe = ">= 1.0.0 and < 2.0.0" + +[dev-dependencies] +gleeunit = ">= 1.0.0 and < 2.0.0" diff --git a/test/root_package_not_compiled_when_running_dep/manifest.toml b/test/root_package_not_compiled_when_running_dep/manifest.toml new file mode 100644 index 000000000..bc12852ec --- /dev/null +++ b/test/root_package_not_compiled_when_running_dep/manifest.toml @@ -0,0 +1,13 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "gleam_stdlib", version = "0.40.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "86606B75A600BBD05E539EB59FABC6E307EEEA7B1E5865AFB6D980A93BCB2181" }, + { name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" }, + { name = "hello_joe", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "hello_joe", source = "hex", outer_checksum = "CC896BC24A45528DE6C59A705171E2DD9F1EA4C3C031428E4A533539EF461519" }, +] + +[requirements] +gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" } +gleeunit = { version = ">= 1.0.0 and < 2.0.0" } +hello_joe = { version = ">= 1.0.0 and < 2.0.0" } diff --git a/test/root_package_not_compiled_when_running_dep/src/root_package_not_compiled_when_running_dep.gleam b/test/root_package_not_compiled_when_running_dep/src/root_package_not_compiled_when_running_dep.gleam new file mode 100644 index 000000000..6258c40aa --- /dev/null +++ b/test/root_package_not_compiled_when_running_dep/src/root_package_not_compiled_when_running_dep.gleam @@ -0,0 +1,3 @@ +pub fn main() { + compilation_error +} diff --git a/test/root_package_not_compiled_when_running_dep/test.sh b/test/root_package_not_compiled_when_running_dep/test.sh new file mode 100755 index 000000000..50d20cf46 --- /dev/null +++ b/test/root_package_not_compiled_when_running_dep/test.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +set -eu + +GLEAM_COMMAND=${GLEAM_COMMAND:-"cargo run --quiet --"} + +g() { + echo "Running: $GLEAM_COMMAND $@" + $GLEAM_COMMAND "$@" +} + +echo Resetting the build directory to get to a known state +rm -fr build + +echo This should succeed regardless of root package compilation errors as it is a dependency module +g run --module=hello_joe +g run --module=hello_joe --target=erlang +g run --module=hello_joe --target=javascript + +echo Running for Erlang should fail, even if previously a Erlang dependency was built +if g run --target=erlang; then + echo "Expected run to fail" + exit 1 +fi + +echo Running for JavaScript should fail, even if previously a JavaScript dependency was built +if g run --target=javascript; then + echo "Expected run to fail" + exit 1 +fi + +echo +echo Success! 💖 +echo