Skip to content

bug - Rust async methods imported through rust-inspect typecheck as synchronous Results but emit futures #607

@dannymeijer

Description

@dannymeijer

Area

  • Compiler (frontend/backend/codegen)
  • Runtime / Core crates (stdlib/core/derive)

Summary

Expected: Rust async methods imported through from rust::... import ... should be represented as awaitable in Incan. A call such as await ctx.register_csv(...) should typecheck when the underlying Rust method returns impl Future<Output = Result<...>>, and the un-awaited call should be rejected or require explicit awaiting before matching on Ok / Err.

Actual: Incan treats ctx.register_csv(...) as a synchronous Result, so the un-awaited source typechecks. The generated Rust then fails because the real DataFusion method returns a future. Adding await in Incan is rejected by the typechecker as though the method already returned Result.

This blocks InQL’s DataFusion backend after the fix for #604: the original ZipIterator failure is gone, but the library now fails at generated Rust compilation on DataFusion async methods.

Reproduction steps

Create a minimal project:

[project]
name = "datafusion_async_repro"
version = "0.1.0"

[rust-dependencies]
datafusion = "53"

Use this src/lib.incn:

import std.async
from rust::datafusion::execution::context import SessionContext
from rust::datafusion::prelude import CsvReadOptions


pub async def register_csv_without_await() -> None:
    ctx = SessionContext.new()
    opts = CsvReadOptions.new()
    match ctx.register_csv("orders", "orders.csv", opts):
        Ok(_) => pass
        Err(_) => pass

Run:

incan build --lib

Then change the call to the awaited form:

    match await ctx.register_csv("orders", "orders.csv", opts):
        Ok(_) => pass
        Err(_) => pass

Run:

incan build --lib

Output / logs

Un-awaited source: Incan accepts it, but generated Rust fails:

error[E0308]: mismatched types
  --> src/lib.rs:14:9
   |
13 |     match ctx.register_csv("orders".into(), "orders.csv".into(), opts) {
   |           ------------------------------------------------------------ this expression has type `impl Future<Output = Result<(), DataFusionError>>`
14 |         Ok(_) => {
   |         ^^^^^ expected future, found `Result<_, _>`
help: consider `await`ing on the `Future`
   |
13 |     match ctx.register_csv("orders".into(), "orders.csv".into(), opts).await {
   |                                                                       ++++++

Awaited source: Incan rejects it before Rust generation:

type error: Type mismatch: expected 'Awaitable[_]', found 'Result[Unit, ?]'
  --> src/lib.incn:11:11
   |
11 |     match await ctx.register_csv("orders", "orders.csv", opts):
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Result must be explicitly unwrapped before use

InQL downstream failure shape:

error[E0308]: mismatched types
   --> src/session/datafusion_backend.rs:114:17
    |
113 |             match ctx.execute_logical_plan(logical_plan) {
    |                   -------------------------------------- this expression has type `impl Future<Output = Result<datafusion::dataframe::DataFrame, DataFusionError>>`
114 |                 Ok(df) => {
    |                 ^^^^^^ expected future, found `Result<_, _>`

Environment

OS: macOS local workspace
Rust: rustc 1.96.0-nightly (362211dc2 2026-03-24)
Incan: incan 0.3.0-dev.49
Incan commit: c89f415e19e894e0b0716318015778247dcf570a on main
Command: incan build --lib

Blocking status: blocks InQL’s v0.3/RFC 025 transition from building the DataFusion backend honestly. A workaround would require hiding these calls behind a custom Rust adapter, which is exactly the kind of workaround InQL should avoid as a showcase package.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingincan compilerSuggestions, features, or bugs related to the Compiler (frontend/backend/codegen)runtime / core cratesSuggestions, features, or bugs related to the `incan-core`, `incan-stdlib`, 'incan-derive` crates

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions