Skip to content

Compiler wrongly detects that a value is assigned to itself #9635

@ageron

Description

@ageron

The compiler wrongly detects that minutes_per_day is assigned to itself in the following code:

Clock :: { hour: U8, minute: U8 }.{
    create : { hour: I64, minute: I64 } -> Clock
    create = |{ hour, minute }| {
        hour24 = (hour % 24 + minute // 60) % 24
        minute60 = minute % 60
        total_minute = ((hour24 * 60 + minute60) % minutes_per_day + minutes_per_day) % minutes_per_day
        hh = (total_minute // 60).to_u8_try() ?? { crash "Unreachable" }
        mm = (total_minute % 60).to_u8_try() ?? { crash "Unreachable" }
        { hour: hh, minute: mm }
    }
}

minutes_per_day = 24 * 60

main! = |_args| {
    clock = Clock.create({hour: 50, minute: 200})
    dbg clock
    Ok({})
}

This error occurs twice (for the 2nd and 3rd occurrence of minutes_per_day on the total_minute = ... line:

Details
-- INVALID ASSIGNMENT TO ITSELF ------------------

The value minutes_per_day is assigned to itself, which would cause an infinite loop at runtime.

Only functions can reference themselves (for recursion). For non-function values, the right-hand side must be fully computable without referring to the value being assigned.

   ┌─ /var/folders/74/7_g_vgn57nzgjh9mw5smp6rc0000gn/T/roc/debug-9f31ffe1/A9MnNbRc8y5vtaJ7k3uYAwocYZY4k2LV/main.roc:12:70
   │
12 │         total_minute = ((hour24 * 60 + minute60) % minutes_per_day + minutes_per_day) % minutes_per_day
   │                                                                      ^^^^^^^^^^^^^^^

-- INVALID ASSIGNMENT TO ITSELF ------------------

The value minutes_per_day is assigned to itself, which would cause an infinite loop at runtime.

Only functions can reference themselves (for recursion). For non-function values, the right-hand side must be fully computable without referring to the value being assigned.

   ┌─ /var/folders/74/7_g_vgn57nzgjh9mw5smp6rc0000gn/T/roc/debug-9f31ffe1/A9MnNbRc8y5vtaJ7k3uYAwocYZY4k2LV/main.roc:12:89
   │
12 │         total_minute = ((hour24 * 60 + minute60) % minutes_per_day + minutes_per_day) % minutes_per_day
   │                                                                                         ^^^^^^^^^^^^^^^


Found 2 error(s) and 0 warning(s) for /var/folders/74/7_g_vgn57nzgjh9mw5smp6rc0000gn/T/roc/debug-9f31ffe1/A9MnNbRc8y5vtaJ7k3uYAwocYZY4k2LV/main.roc.

Note that moving the definition of minutes_per_day inside the create function works around the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions