Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CS8344 error even with C# 13 (ref in iterators/async) #74793

Closed
ufcpp opened this issue Aug 17, 2024 · 1 comment · Fixed by #74800
Closed

CS8344 error even with C# 13 (ref in iterators/async) #74793

ufcpp opened this issue Aug 17, 2024 · 1 comment · Fixed by #74800
Assignees
Labels
Milestone

Comments

@ufcpp
Copy link
Contributor

ufcpp commented Aug 17, 2024

Version Used:

VS 17.12.0 Preview 1.0
C# Tools 4.12.0-1.24379.11+cf82d399c36008e7936d545cde24141f8d3790fa

Steps to Reproduce:

static async Task M1()
{
    // CS8344.
    foreach (var r in new E1()) ;

    await Task.Yield();

    // No error with C# 13.
    E1 e1 = new();
    while (e1.MoveNext()) { var x = e1.Current; }

    await Task.Yield();

    // No error with C# 13.
    foreach (ref var x in new E2()) ;

    await Task.Yield();

    // No error with C# 13.
    E2 e2 = new();
    while (e2.MoveNext()) { ref var x = ref e2.Current; }
}

static IEnumerable<object?> M2()
{
    // CS8344.
    foreach (var r in new E1()) ;

    yield return null;

    // No error.
    E1 e1 = new();
    while (e1.MoveNext()) { var x = e1.Current; }

    yield return null;

    // No error with C# 13.
    foreach (ref var x in new E2()) ;

    yield return null;

    // No error with C# 13.
    E2 e2 = new();
    while (e2.MoveNext()) { ref var x = ref e2.Current; }
}

ref struct E1
{
    public E1 GetEnumerator() => this;
    public bool MoveNext() => false;
    public int Current => 0;
}

struct E2
{
    public E2 GetEnumerator() => this;
    public bool MoveNext() => false;
    public ref int Current => ref System.Runtime.CompilerServices.Unsafe.NullRef<int>();
}

Expected Behavior:

No error with the ref/unsafe in iterators/async feature.

Actual Behavior:

CS8344 error on the foreach.

I am not sure if this is a bug as it is not on the proposal document, but I would consider this to be a specification omission.

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Aug 17, 2024
@jjonescz
Copy link
Member

Thanks for reporting this. The feature did not change anything about the CS8344 error which disallows ref struct enumerators inside async/iterator methods (although the enumerable itself can be a ref struct). I think there is no reason for keeping this error; we could simply remove it in C# 13 and let the ref-in-async feature disallow unsafe usages (i.e., it would still disallow the foreach on ref struct enumerator if there are any awaits or yield returns in its body).

It doesn't look like the CS8344 error is part of the C# spec, so no spec changes are needed.

@jjonescz jjonescz self-assigned this Aug 20, 2024
@jaredpar jaredpar added this to the 17.12 milestone Aug 21, 2024
@jcouv jcouv added 4 - In Review A fix for the issue is submitted for review. and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants