Skip to content

Explicit tests covering scoped in T extension methods should be added. #78491

Closed
@tannergooding

Description

@tannergooding

Background

The language today allows you to define a method of the form RefStruct M(scoped in T value) which indicates that the in will not be captured in the resulting ref struct which makes code such as the following safe:

public ref struct MyRefStruct
{
    private Span<int> _span;

    public MyRefStruct(Span<int> x)
    {
        _span = C.M(x);
    }
}

public static class C
{
    public static Span<int> M(scoped in Span<int> span)
    {
        return span;
    }
}

Likewise, the language allows you to declare extension methods that take a value type T by reference or by readonly reference and so public static Span<int> M(in this Span<int> span) and public static Span<int> M(ref this Span<int> span) are both valid. However, the language does not currently allow you to declare a scoped in extension method and errors for the following: public static Span<int> M(scoped in this Span<int> span). Thus the following code errors:

public ref struct MyRefStruct
{
    private Span<int> _span;

    public MyRefStruct(Span<int> x)
    {
        // CS1061: 'Span<int>' does not contain a definition for 'M' and no accessible extension method 'M' accepting a first argument of type 'Span<int>' could be found (are you missing a using directive or an assembly reference?)
        _span = x.M();
    }
}

public static class C
{
    // CS1031: Type expected
    // CS1001: Identifier expected
    // CS1003: Syntax error, ',' expected
    // CS1100: Method 'M' has a parameter modifier 'this' which is not on the first parameter
    public static Span<int> M(scoped in this Span<int> span)
    {
        return span;
    }
}

However, the new C# 14 extension members feature does allow this and the following works just fine:

public ref struct MyRefStruct
{
    private Span<int> _span;

    public MyRefStruct(Span<int> x)
    {
        _span = x.M();
    }
}

public static class C
{
    extension(scoped in Span<int> span)
    {
        public Span<int> M()
        {
            return span;
        }
    }
}

Expected Outcome

After talking with @jaredpar, it is believed that this was likely just an oversight that this doesn't work with the pre-C# 14 extension feature. However, it was noted that there are no tests for scoped in this or extension(scoped in T name) in the codebase and such explicit tests should likely be added (at least for the new C# 14 extension members feature). It may also be worth adding test for extension(scoped ref T name).

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions