Skip to content

bug - Decorator and imported const str arguments are not materialized as str call arguments #638

@dannymeijer

Description

@dannymeijer

Thanks for reporting! Please include a minimal reproduction when possible.

Area

  • Compiler (frontend/backend/codegen)

Summary

Expected: an imported pub const TOKEN: str = "token" should be usable anywhere a str argument is accepted, matching same-file constants and string literals. If authors explicitly call TOKEN.to_string(), codegen should emit stable Rust that materializes an owned string on the supported toolchain.

Actual: the typechecker accepts both shapes, but generated Rust fails to compile after module import:

  • identity(TOKEN) emits a call where the callee expects String and the imported constant is still &str.
  • identity(TOKEN.to_string()) emits TOKEN.as_str().to_string(), which hits unstable Rust str_as_str on the current nightly.

This surfaced while implementing InQL RFC 014 function registry decorators. The InQL workaround is to use String.from(TOKEN) at decorator/test call sites, but that should not be required for ordinary imported str constants.

Reproduction steps

  1. Create src/registry.incn:
"""Tiny module exporting one public string constant."""

pub const TOKEN: str = "token"
  1. Create tests/test_imported_const_str_argument.incn:
"""Minimal repro for imported public const `str` call-argument materialization."""

from registry import TOKEN


def identity(value: str) -> str:
    """Return the provided string value."""
    return value


def test_imported_const_str_argument_materializes() -> None:
    """Passing an imported const str to a str parameter should compile and preserve the value."""
    assert identity(TOKEN) == "token", "imported const str should be accepted as a str argument"
  1. Create tests/test_imported_const_str_to_string.incn:
"""Minimal repro for `to_string()` on imported public const `str` call arguments."""

from registry import TOKEN


def identity(value: str) -> str:
    """Return the provided string value."""
    return value


def test_imported_const_str_to_string_materializes() -> None:
    """Calling `to_string()` on an imported const str should compile on the supported Rust toolchain."""
    assert identity(TOKEN.to_string()) == "token", "imported const str to_string should materialize an owned string"
  1. Run:
incan test tests

Output / logs

Direct imported const argument:

error[E0308]: mismatched types
  --> src/lib.rs:14:18
   |
14 |     if (identity(TOKEN)) != ("token") {
   |         -------- ^^^^^ expected `String`, found `&str`
   |         |
   |         arguments to this function are incorrect
   |
note: function defined here
  --> src/lib.rs:8:4
   |
 8 | fn identity(value: String) -> String {
   |    ^^^^^^^^ -------------
help: try using a conversion method
   |
14 |     if (identity(TOKEN.to_string())) != ("token") {
   |                       ++++++++++++

Explicit .to_string() workaround:

error[E0658]: use of unstable library feature `str_as_str`
  --> src/lib.rs:14:24
   |
14 |     if (identity(TOKEN.as_str().to_string())) != ("token") {
   |                        ^^^^^^
   |
   = note: see issue #130366 <https://github.com/rust-lang/rust/issues/130366> for more information

Environment

OS: macOS
Rust: rustc 1.96.0-nightly (362211dc2 2026-03-24)
Incan: 0.3.0-rc7 candidate, observed on commit 3fc6ea7f from PR #637
Command: incan test tests

Blocking status / workaround

Non-blocking for InQL RFC 014. A valid workaround is to materialize imported string constants with String.from(TOKEN) at the call site. That preserves semantics, but it is noisy and should not be required for normal str argument passing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingincan compilerSuggestions, features, or bugs related to the Compiler (frontend/backend/codegen)

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions