Skip to content

[Version 13.0] Feature support for ref and unsafe in iterators and async - #1781

Draft
RexJaeschke wants to merge 3 commits into
draft-v13from
v13-ref-and-unsafe-in-iterators-and-async
Draft

[Version 13.0] Feature support for ref and unsafe in iterators and async#1781
RexJaeschke wants to merge 3 commits into
draft-v13from
v13-ref-and-unsafe-in-iterators-and-async

Conversation

@RexJaeschke

Copy link
Copy Markdown
Contributor

This is Rex's adaptation of the corresponding MS proposal.

@RexJaeschke RexJaeschke added this to the C# 13 milestone Aug 13, 2026
@RexJaeschke RexJaeschke added type: feature This issue describes a new feature Review: pending Proposal is available for review labels Aug 13, 2026
@RexJaeschke
RexJaeschke marked this pull request as draft August 13, 2026 10:48
Comment thread standard/statements.md
If *ref_kind* is `ref readonly`, the *identifier*s being declared are references to variables that are treated as read-only. Otherwise, if *ref_kind* is `ref`, the *identifier*s being declared are references to variables that shall be writable.

It is a compile-time error to declare a ref local variable, or a variable of a `ref struct` type, within a method declared with the *method_modifier* `async`, or within an iterator ([§15.15](classes.md#1515-synchronous-and-asynchronous-iterators)).
It is a compile-time error to declare and use (even implicitly in compiler-synthesized code) a ref local variable, or a variable of a `ref struct` type across `await` expressions or `yield return` statements. More precisely, the error is driven by the following mechanism: after an `await` expression or a `yield return` statement, all ref local variables and variables of a `ref struct` type in scope are considered definitely unassigned.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, that means it is permissible to read a ref local variable in unreachable code.

using System.Collections.Generic;

public class C {
    public IEnumerator<int> M() {
        int i = 0;
        ref int r = ref i;

        yield return r; // OK
        // r is definitely unassigned, because of the yield return above.

        // yield return r; // error

        yield break;
        // r is again definitely assigned, because this point is unreachable.

        yield return r; // OK
    }
}

Comment thread standard/statements.md
If *ref_kind* is `ref readonly`, the *identifier*s being declared are references to variables that are treated as read-only. Otherwise, if *ref_kind* is `ref`, the *identifier*s being declared are references to variables that shall be writable.

It is a compile-time error to declare a ref local variable, or a variable of a `ref struct` type, within a method declared with the *method_modifier* `async`, or within an iterator ([§15.15](classes.md#1515-synchronous-and-asynchronous-iterators)).
It is a compile-time error to declare and use (even implicitly in compiler-synthesized code) a ref local variable, or a variable of a `ref struct` type across `await` expressions or `yield return` statements. More precisely, the error is driven by the following mechanism: after an `await` expression or a `yield return` statement, all ref local variables and variables of a `ref struct` type in scope are considered definitely unassigned.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not clear to me that this disallows the following:

using System.Threading.Tasks;

public class C {
    public static async Task M(Task<int> t) {
        int i = 0;
        ref int r = ref i;
        K1(ref r, await t); // error
    }
    
    private static void K1(ref int r, int i) {}
}

One could claim that ref r is evaluated before the await expression and r is still definitely assigned at that point. So this depends on the "compiler-synthesized code" for await expressions but I'm not sure that is specified rigorously enough to say whether the above is allowed.

BillWagner added a commit that referenced this pull request Aug 18, 2026
…nd unsafe in iterators and async

Source: #1781
Head SHA: e437a3c

Apply ref and unsafe in iterators and async feature patch from PR #1781 to alpha-v13.
3 files modified: classes.md, statements.md, unsafe-code.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review: pending Proposal is available for review type: feature This issue describes a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants