Skip to content

Conversation

@IgorCastejon
Copy link

Closes #5261.

  • The changes in this PR have been discussed beforehand in an issue
  • The issue for this PR has been linked
  • Tests have been added for new behaviour
  • The changelog has been updated for any user-facing changes

Comment on lines +228 to +235
ValueConstructorVariant::ModuleConstant { .. } => {
// If the variable is a constant we shadow it with the refined type.
// We cannot convert it to a local variable as that would cause the
// code generator to look for a runtime variable that doesn't exist.
let mut refined_constant = variable.clone();
refined_constant.type_ = type_;
let _ = self.environment.scope.insert(name, refined_constant);
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this specific block to allow field access of const records (like user.name) to work inside the branch, matching the current behavior for local variables.

However, I noticed that Gleam doesn't do this type refinement for constants globally:
Gleam playground

Since the fix for the runtime crash doesn't strictly require this part (we could just ignore ModuleConstant entirely here), I have two questions:

  1. Should I keep or remove this code?
  2. Should I open a separate issue about global type refinement for constants (or is the current behavior deliberate)?

Comment on lines +2 to +22
source: compiler-core/src/javascript/tests/case.rs
expression: "\npub type Wibble {\n Wibble\n Wobble(int: Int)\n}\n\nconst wibble = Wibble\n\npub fn main() {\n echo wibble\n // This 'wibble' shadows the const\n let wibble = Wobble(42)\n case wibble {\n // This matches the local variable, not the const\n Wobble(_) -> wibble\n }\n}\n"
---
----- SOURCE CODE

pub type Wibble {
Wibble
Wobble(int: Int)
}

const wibble = Wibble

pub fn main() {
echo wibble
// This 'wibble' shadows the const
let wibble = Wobble(42)
case wibble {
// This matches the local variable, not the const
Wobble(_) -> wibble
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just something of interest I noticed while testing: if a const is defined but unused, it is properly optimized out of the generated JavaScript, but it still seems to have its name reserved in the variable generator.
Gleam playground

@IgorCastejon IgorCastejon force-pushed the fix/const-record-as-case-subject-bug branch from 90fd708 to a071320 Compare January 19, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Erlang target: "unbound variable" error when referencing a const record inside a case expression

1 participant