Repository: gleam-lang/gleam (rust)
Issue: Improve "Unknown module field" error message
I think the error message we get when trying to access a module function that doesn't exist could be improved. Right now it looks like this:

![Screenshot 2024-08-19 alle 20 13 49](https://github.com/user-attachments/assets/3ab2c635-e2c1-4faf-9e61-b26a2f7f629f)

Calling it "module field" strikes me as a bit odd, I've never heard this term before. Maybe it could be worded a bit differently:

```diff
+error: Unknown module function
-error: Unknown module field
   ┌─ /Users/giacomocavalieri/Documents/progetti/ssg/build/packages/jot/src/jot.gleam:20:11
   │
20 │       dict.update(attributes, key, fn(previous) {
   │           ^^^^^^^

+The module `gleam/dict` does not have a `update` function.
-The module `gleam/dict` does not have a `update` field.
```

Pull request description: improve error title for unknown module value
This closes #3534, as suggested by Louis I went with "unknown module value" since it's also how it is referred to in the error message itself instead of "module field"

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ebe9e693..478818289 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -233,9 +233,12 @@
   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
+- 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))
+
 ### Formatter
 
 - The formatter now adds a `todo` after a `use` expression if it is the last
@@ -363,7 +366,8 @@
   unused.
   ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
 
-- The Language Server now correctly shows completions for values in the Gleam prelude.
+- The Language Server now correctly shows completions for values in the Gleam
+  prelude.
   ([Surya Rose](https://github.com/GearsDatapacks))
 
 ## v1.4.1 - 2024-08-04
diff --git a/compiler-core/src/error.rs b/compiler-core/src/error.rs
index 54e1869fb..382ec50ab 100644
--- a/compiler-core/src/error.rs
+++ b/compiler-core/src/error.rs
@@ -2020,7 +2020,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,


Test patch:
diff --git a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__type_imported_as_value.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__type_imported_as_value.snap
index d8f2eb378..a5c954e96 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__type_imported_as_value.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__import_type_duplicate.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__import_type_duplicate.snap
index 95120d399..8076640d9 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__import_type_duplicate.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__unqualified_import_errors_do_not_block_later_unqualified.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__unqualified_import_errors_do_not_block_later_unqualified.snap
index d76d7d091..5d51aff74 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__unqualified_import_errors_do_not_block_later_unqualified.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__unqualified_using_opaque_constructo.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__unqualified_using_opaque_constructo.snap
index 665a2e679..dff15b955 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__unqualified_using_opaque_constructo.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__unqualified_using_private_constructo.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__unqualified_using_private_constructo.snap
index 3551c4438..736aff555 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__unqualified_using_private_constructo.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__unqualified_using_private_constructor_pattern.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__unqualified_using_private_constructor_pattern.snap
index a08baf14f..097eacc41 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__unqualified_using_private_constructor_pattern.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__unqualified_using_private_function.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__unqualified_using_private_function.snap
index 1a0996479..c7d0b85b0 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__unqualified_using_private_function.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__using_opaque_constructo.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_opaque_constructo.snap
index e065c5903..5b81d6d60 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_opaque_constructo.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__using_private_constructo.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_constructo.snap
index e065c5903..5b81d6d60 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_constructo.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__using_private_constructor_pattern.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_constructor_pattern.snap
index e0a304c44..26aac0c69 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_constructor_pattern.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__using_private_custom_type.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_custom_type.snap
index c4f13a47c..e92a44857 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_custom_type.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__using_private_external_type.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_external_type.snap
index c4f13a47c..e92a44857 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_external_type.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__using_private_function.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_function.snap
index 86ca098b9..a4f430ae9 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_function.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__using_private_type_alias.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_type_alias.snap
index c4f13a47c..e92a44857 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_type_alias.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__using_private_unqualified_custom_type.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_unqualified_custom_type.snap
index afbd5eacd..67cf6848d 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_unqualified_custom_type.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__using_private_unqualified_external_type.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_unqualified_external_type.snap
index afbd5eacd..67cf6848d 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_unqualified_external_type.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/gleam_core__type___tests__imports__using_private_unqualified_type_alias.snap b/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_unqualified_type_alias.snap
index afbd5eacd..67cf6848d 100644
--- a/compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__imports__using_private_unqualified_type_alias.snap
+++ b/compiler-core/src/type_/tests/snapshots/gleam_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/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.
-