Skip to content

Use local module appropriate names when printing types in warnings #4164

@xhalo32

Description

@xhalo32
gleam@20fb6f41b

The following code suggests incorrect type for todo

pub fn curry(f: fn(a, b) -> c) -> fn(a) -> fn(b) -> c {
    fn(a: a) {
        todo
    }
}

producing a warning which suggests

[snip]
Hint: I think its type is `fn(a) -> c`.

which is obviously incorrect as todo should be replaced with a function of type fn(b) -> c.

Investigation

I have been digging in /compiler-core/_type/pretty.rs and added tests:

    assert_string!(
        fn_(
            vec![Arc::new(Type::Var {
                type_: Arc::new(RefCell::new(TypeVar::Generic { id: 78 })),
            })],
            fn_(
                vec![Arc::new(Type::Var {
                    type_: Arc::new(RefCell::new(TypeVar::Generic { id: 2 })),
                })],
                Arc::new(Type::Named {
                    args: vec![],
                    module: "whatever".into(),
                    package: "whatever".into(),
                    name: "Bool".into(),
                    publicity: Publicity::Public,
                    inferred_variant: None,
                }),
            ),
        ),
        "fn(a) -> fn(b) -> Bool",
    );

and

    assert_eq!(
        pretty_print(fn_(vec![], fn_(vec![], int()))),
        "fn() -> fn() -> Int"
    );

which both pass, so I guess the issue is not related to the pretty printer but rather happens somewhere in the type system.

Testing

I added the following snap test which currently fails

---
source: compiler-core/src/type_/tests/warnings.rs
expression: "pub fn main() {\n          todo()\n        }"
---
----- SOURCE CODE
pub fn curry(f: fn(a, b) -> c) -> fn(a) -> fn(b) -> c {
            fn(a: a) {
                todo
            }
        }

----- WARNING
warning: Unused variable
  ┌─ /src/warning/wrn.gleam:1:14
  │
1 │ pub fn curry(f: fn(a, b) -> c) -> fn(a) -> fn(b) -> c {
  │              ^^^^^^^^^^^^^^^^ This variable is never used

Hint: You can ignore it with an underscore: `_f`.

warning: Unused variable
  ┌─ /src/warning/wrn.gleam:2:16
  │
2 │             fn(a: a) {
  │                ^^^^ This variable is never used

Hint: You can ignore it with an underscore: `_a`.

warning: Todo found
  ┌─ /src/warning/wrn.gleam:3:17
  │
3 │                 todo
  │                 ^^^^ This code is incomplete

This code will crash if it is run. Be sure to finish it before
running your program.

Hint: I think its type is `fn(b) -> c`.
-old snapshot
+new results
────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   29    29 │ 
   30    30 │ This code will crash if it is run. Be sure to finish it before
   31    31 │ running your program.
   32    32 │ 
   33       │-Hint: I think its type is `fn(b) -> c`.
         33 │+Hint: I think its type is `fn(a) -> b`.

Further questions

The issue might be present with panic as well as the code follows similar logic as todo's code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedContributions encouraged

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions