Skip to content

fix: emit implicit enum selectors in struct field defaults - #2225

Closed
mvanhorn wants to merge 1 commit into
grayscale-lang:batch/august-1-2026from
mvanhorn:fix/2223-implicit-enum-struct-default
Closed

fix: emit implicit enum selectors in struct field defaults#2225
mvanhorn wants to merge 1 commit into
grayscale-lang:batch/august-1-2026from
mvanhorn:fix/2223-implicit-enum-struct-default

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Related issue

Closes #

Summary

Update the existing struct-default initializer path in grayc/src/codegen/codegen.c so it emits an implicit enum selector using the field's declared enum type as context. Reuse the production expression/codegen behavior that already handles implicit enum selectors in struct literal fields and other contextually typed positions, keeping explicit enum selectors and non-enum defaults unchanged. Add a focused passing integration program that declares an enum-typed field with an implicit-selector default, constructs the struct without overriding that field, and verifies the resulting value; include an explicit-selector default or override in the same test as a parity guard.

The typechecker accepts an implicit enum selector such as .PENDING as the default value of an enum-typed struct field, but the code generator emits no C expression for that default. Constructing the struct with the field omitted therefore produces an initializer like .status = } and leaks a C compiler error. The equivalent explicit selector, Status.PENDING, works, and implicit selectors already work in other expression contexts. There are no assignees, competing pull requests, comments claiming the work, or closed prior attempts in the supplied issue bundle.

Closes #2223

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Tests
  • Documentation
  • CI/Build

Breaking changes

None.

Checklist

  • make build compiles with zero warnings
    Not run: no test command resolved in this workspace, so nothing was executed to pass.
  • No @ before module names in any text (it tags GitHub users)
    Not run: no test command resolved in this workspace, so nothing was executed to pass.

If adding user-facing stdlib/builtin/type

  • C implementation in grayc/src/stdlib/<module>.h and .c (with @man block)
    Not run: no test command resolved in this workspace, so nothing was executed to pass.
  • Typechecker wired: return type, stdlib_arg_table[], stdlib_arg_type_table[], _using_funcs[]
    Not run: no test command resolved in this workspace, so nothing was executed to pass.
  • Codegen wired: emit_<module>_call()
    Not run: no test command resolved in this workspace, so nothing was executed to pass.
  • STANDARD.md updated
    Not run: no test command resolved in this workspace, so nothing was executed to pass.
  • ./scripts/generate_stdlib_man.sh run and output committed
    Not run: no test command resolved in this workspace, so nothing was executed to pass.

AI was used for assistance.

@SchoolyB

Copy link
Copy Markdown
Member

Good to see ya back contributing @mvanhorn 🚀 Will review this when I can later today

@SchoolyB SchoolyB left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@mvanhorn The fix for struct literals is solid 👍🏾 , I verified
One thing though — the same bug exists in the new(Struct) path and this PR doesn't
cover it. If you do something like:

const Task struct {
    status Status = .PENDING
}


const Status enum {
    PENDING
}

do main() {
    mut t = new(Task)
    println("${t^.status}")
}

It still emits _np->status = ; and leaks a C compiler error. The default emission
loop in the new() codegen path needs the same current_var_type save/restore you
applied to the struct literal path. Would be good to add a new(Task) case to the
integration test as well.

@SchoolyB
SchoolyB changed the base branch from main to batch/august-1-2026 July 31, 2026 18:33
@SchoolyB
SchoolyB deleted the branch grayscale-lang:batch/august-1-2026 July 31, 2026 22:59
@SchoolyB SchoolyB closed this Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: In Review This PR is being reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: implicit enum selector in struct field default emits empty C expression

2 participants