Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

f-string interpolation calls `str` by name, so a user binding named `str` changes every f-string

Open
#1,322 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
68/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
c

Research direction

Start in the f-string block of src/lexer.c and inspect the lowering used by the VM, then compare the ouroboros frontend/AOT path. Run the two reproductions with EIGS_JIT_OFF=1 and use tests/test_fstrings.eigs as the regression-test entry point. Done means the global, defined, and function-local str cases produce the specified result or fail loudly, with both lowering paths aligned.

Written by the indexing model from the issue text.

Description

area:runtime-vm bug kind:silent-wrong

The lexer lowers f"a{e}b" to ("a" + (str of (e)) + "b") using an ordinary TOK_IDENT "str" (src/lexer.c, f-string block). That identifier is resolved like any other name at run time. A program that binds str therefore changes, or breaks, every f-string evaluated in that scope. Nothing in the source of the f-string mentions str.

Reproduce (origin/main 94c4c5b, release build)

define str(x) as:
    return "HIJACK"
print of f"<{5}>"

Actual: exit 0, stdout <HIJACK>. Expected: <5> (or a loud error, if rebinding str is to be forbidden).

str is 3
print of f"<{str}>"

Actual: exit 1, Error line 2: cannot call num. The failing call is one the user never wrote.

The first case is a silent wrong answer (PRINCIPLES.md §2). A str local inside a function body does the same thing to every f-string in that function.

Done when

  • f-string interpolation converts values with the builtin conversion no matter what str is bound to in the enclosing scopes (for example, a dedicated opcode or a reserved internal name the user cannot bind). The alternative is a decision, recorded here, that rebinding str is an error.
  • Both programs above print <5> and <3> (or fail loudly at the rebinding, if that is the decision), under the VM and with EIGS_JIT_OFF=1.
  • A regression in tests/test_fstrings.eigs covers a global str, a define str, and a function-local str.
  • The ouroboros frontend/AOT mirror whatever lowering is chosen (it lowers f-strings the same way).

Found while fixing #1244, where the synthetic str token is now marked as having no source span so LSP rename never edits it; this issue is about the runtime meaning of that token.

Dominant language
C
Stars
3
Forks
7
Avg merge
4h 15m
Merged PRs (30d)
106

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from InauguralSystems/EigenScript

All issues in InauguralSystems/EigenScript

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.