Skip to content

Type checker infers every user-defined action's return type as Nothing, causing spurious "Expected Text but found Nothing" at call sites #569

Description

@logbie

Summary

The type checker does not infer the return type of a user-defined action. A call result is treated as Nothing, so whenever that result is passed to a builtin position that expects Textrespond to req with …, open file at …, etc. — it prints a (non-fatal) error[ERROR]: … Expected Text but found Nothing, even though the value is Text at runtime and the program runs correctly.

This is the same family flagged as parenthetical "minor adjacent notes" in #557 and #558 ("the type checker doesn't infer an action's return type"); filing it standalone with an isolated repro since those were closed on their primary topics.

Environment

  • wfl 26.7.8, Linux release build (cargo build --release)

Minimal reproduction

Even the simplest action — returning a plain concatenated string — triggers it:

define action called h with parameters name:
    store greeting as "hello "
    return greeting with name
end action

listen on port 8095 as s
wait for request comes in on s as req
store c as call h with "world"
respond to req with c and content_type "text/plain"

Running it prints:

Type checking warnings:
error[ERROR]: Response content must be text - Expected Text but found Nothing
    ┌─ repro.wfl:…
    │     respond to req with c and content_type "text/plain"

…yet the server responds hello world with 200. The error is emitted for the respond line because call h … is typed Nothing.

What is / isn't affected

  • Inlining the value (no action) is fine: store c as read content from f then respond to req with c produces no error.
  • Using an action result is always flagged, independent of the body:
    • action returning "literal" with name → flagged
    • action returning read content from f → flagged
    • action returning a value first store out as "" then change out to read content from f → flagged
  • Same root cause surfaces at open file at <call-result> (per Enhancement: outbound HTTP client needs POST/headers/auth (and HMAC-SHA256) for real API integrations (e.g. Stripe) #558's note) — anywhere a Text parameter meets an action-call result.

So the trigger is "result of a user-defined action used where Text is required," i.e. the action's declared/inferred return type is Nothing rather than the type of its return expression.

Impact

Non-fatal (labeled error[ERROR] but execution continues), but noisy: any real program that factors request handling / file reading into actions and passes results to respond/open file prints a wall of these on every run. It undermines principle #4 (clear, trustworthy error reporting) — a real type error would be lost in the false positives. Concretely, a dynamic WFL web server (route handlers returning HTML/JSON, static-asset readers, an ACME-challenge reader) prints one per handler.

Expected

Infer an action's return type from its return expression(s) (union when they differ), so a call result carries that type at the call site. At minimum, don't emit a Text-mismatch error when the value's type is unknown/Nothing due to un-inferred action returns.

Discovered while

Adding native HTTPS + Let's Encrypt (ACME HTTP-01) support to a WFL web app — the challenge/asset/route handlers are all actions whose results feed respond to req with ….

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions