Skip to content

cgen, closures: mut capture of a pointer-alias type emits a one-deref-short member access #27355

@medvednikov

Description

@medvednikov

Description

When a closure captures a variable by mut whose type is an alias of a pointer (type AppRef = &App), cgen stores the capture in the closure context struct as a double pointer (AppRef* app;, i.e. App**), but the closure body emits only a single dereference (_V_closure_ctx->app->field). The C compiler then rejects the member access because _V_closure_ctx->app is itself a pointer.

A non-mut capture of the same alias compiles correctly, which isolates the extra (unaccounted-for) pointer level to the mut capture path.

V version: V 0.5.1, current master (5e36217f8)
OS/Backend: reproduced on macOS arm64; originally reported on Linux (a _V_closure_ctx->app member-reference error from a captured pointer).

Reproducer

struct App {
mut:
	score int
}

type AppRef = &App

fn make_handler(mut app AppRef) fn () {
	return fn [mut app] () {
		app.score++
	}
}

fn main() {
	mut a := App{}
	h := make_handler(mut &a)
	h()
}

Compile with:

v file.v

Current behavior

error: member reference base type 'main__AppRef' (aka 'struct main__App *') is not a structure or union
  _V_closure_ctx->app->score++;

The generated context struct field is main__AppRef* app; (a struct main__App **), but the body accesses it as _V_closure_ctx->app->score (one deref short). It should be either (*_V_closure_ctx->app)->score, or the field should be stored as main__AppRef (single pointer).

Expected behavior

The captured-pointer member access in the closure body should match the pointer level of the context-struct field, so the program compiles.

Notes

  • Reported via the bugs.vlang.io crash reporter (a '_V_closure_ctx->app' is a pointer; did you mean to use '->'? variant from a captured pointer in a closure). This reproducer is the same closure-captured-pointer member-access family; the operator/pointer-level mismatch direction differs.

Note

You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugs.vlang.ioReported via the bugs.vlang.io crash reporter

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions