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

False non-copyable report #7389

Open
333fred opened this issue Aug 22, 2024 · 3 comments
Open

False non-copyable report #7389

333fred opened this issue Aug 22, 2024 · 3 comments

Comments

@333fred
Copy link
Member

333fred commented Aug 22, 2024

Analyzer

Diagnostic ID: RS0042: Unsupported use of non-copyable type 'Microsoft.AspNetCore.Razor.PooledObjects.PooledArrayBuilder<Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxToken>' in 'LocalReference' operation

Analyzer source

NuGet Package: Roslyn.Diagnostics.Analyzers

Version: 3.11.0-beta1.24170.2

Describe the bug

When using a non-copyable struct in a list pattern, RS0042 erroneously fires.

Steps To Reproduce

  1. Create a collection type that supports list patterns, and mark it non-copyable.
  2. Use that collection in a list pattern.

Expected behavior

No errors

Actual behavior

RS0042: Unsupported use of non-copyable type 'Microsoft.AspNetCore.Razor.PooledObjects.PooledArrayBuilder<Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxToken>' in 'LocalReference' operation

Additional context

@333fred
Copy link
Member Author

333fred commented Aug 22, 2024

image
As an example.

@sharwell
Copy link
Member

sharwell commented Aug 23, 2024

In reviewing this code on SharpLab, it looks like there are some cases where a shadow copy of the pattern variable is made. The first step of resolving this will be identifying cases where the value is definitely known to not be copied.

using System;
using System.Collections;
using System.Collections.Generic;

public class C {
    C2 _value;

    public void M() {
        using var value = default(C2);

        // no copy here
        if (value is [.., string s])
        {
            return;
        }
    }

    public void M2() {
        // copy here, even though _value is not marked readonly
        if (_value is [.., string s2])
        {
            return;
        }
    }
}

public struct C2 : IEnumerable<object>, IDisposable
{
    public int Count => 1;

    public object this[int index] => throw new NotImplementedException();

    public void Dispose()
    {
        throw new NotImplementedException();
    }

    public IEnumerator<object> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

@333fred
Copy link
Member Author

333fred commented Aug 23, 2024

I would allow it in all cases. A list pattern is simply an enumeration: if that affects the state of the struct, then it's already broken.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants