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

Code fix for IDE0028 produces invalid collection expression #71240

Closed
meziantou opened this issue Dec 12, 2023 · 13 comments
Closed

Code fix for IDE0028 produces invalid collection expression #71240

meziantou opened this issue Dec 12, 2023 · 13 comments
Assignees
Labels
Area-IDE Feature - Collection Expressions Resolution-By Design The behavior reported in the issue matches the current design
Milestone

Comments

@meziantou
Copy link
Contributor

Version Used: '4.9.0-2.23578.7 (984df16)'. Language version: 12.0

Steps to Reproduce:

The actual use case is using Xunit.TheoryData<T>, but here's a small repro

public class UnitTest1
{
    void A()
    {
        Sample<string> a = new Sample<string> // IDE0028: Collection expression can be simplified
        {
            "test",
        };

        // After applying the fix
        Sample<string> a =
        [
            "test", // CS0029 Cannot implicitly convert type 'string' to 'object[]' 
        ];
    }
}

class Sample<T> : IEnumerable<object[]>
{
    public void Add(T p) => throw null;
    IEnumerator IEnumerable.GetEnumerator() => throw null;
    IEnumerator<object[]> IEnumerable<object[]>.GetEnumerator() => throw null;
}

Diagnostic Id: IDE0028

Expected Behavior: The code is valid after applying the code fix

Actual Behavior: The build fails

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Dec 12, 2023
@CyrusNajmabadi
Copy link
Member

@cston @RikkiGibson this seems strange. This is a legal collection initializer type. And we're not using the collection builder attribute. I would expect the to be a legal target, with the expressions validated against the add metgod.

Do you know why this fails?

@cston
Copy link
Member

cston commented Dec 13, 2023

The element expressions must be convertible to the enumerable element type, in this case to object[].

From Conversions:

  • To a struct or class type that implements System.Collections.Generic.IEnumerable<T> where:

    • For each element Ei there is an implicit conversion to T.

@CyrusNajmabadi
Copy link
Member

That applies to All collections chuck? Not just Collection-Builder collections? I don't think i realized that :(

I suppose it works for everything else, but does put us in this awkward spot with these sort of collection-initializers.

Hrmm... Will have to noodle on this a bit.

@sharwell
Copy link
Member

sharwell commented Dec 28, 2023

It's weird that collection expressions don't behave the same way as collection initializers here. For the above type, both of the following fail:

Sample<string> a =
[
  "test", // CS0029 Cannot implicitly convert type 'string' to 'object[]' 
];
Sample<string> a =
[
  ["test"], // CS1950 The best overloaded Add method 'Sample<string>.Add(string)' for the collection initializer has some invalid arguments
];

📝 Note that Xunit's TheoryData<T> type falls victim to this issue

@jaredpar
Copy link
Member

Resolving as a dupe of 72098

@jaredpar jaredpar added the Resolution-Duplicate The described behavior is tracked in another issue label Mar 26, 2024
@cston
Copy link
Member

cston commented Mar 27, 2024

Reopening since this is not a duplicate of #72098.

@cston cston reopened this Mar 27, 2024
@cston cston removed the Resolution-Duplicate The described behavior is tracked in another issue label Mar 27, 2024
@cston
Copy link
Member

cston commented Mar 27, 2024

Closing as by design since element expressions must be convertible to the enumerable element type as mentioned above.

@cston cston closed this as completed Mar 27, 2024
@cston cston added the Resolution-By Design The behavior reported in the issue matches the current design label Mar 27, 2024
@spanglerco
Copy link

spanglerco commented Mar 28, 2024

By design for collection expressions makes sense, but what about IDE0028? A code analysis rule shouldn't say to switch from valid code to invalid code. How it is now, I need to add a suppression every time I want to use TheoryData with a collection initializer.

Edit: At least for TheoryData specifically, the xunit maintainer added a workaround in the form of a constructor that takes in T[], enabling new TheoryData<string>(["value"]).

@CyrusNajmabadi
Copy link
Member

A code analysis rule shouldn't say to switch from valid code to invalid code.

The invalid code is a bug in the compiler that is being fixed currently.

@cston
Copy link
Member

cston commented Mar 28, 2024

The invalid code is a bug in the compiler that is being fixed currently.

The compiler bug that is being fixed will no longer require the Add method to be callable with an argument of the iteration type (see dotnet/csharplang#8022), but each element must still be implicitly convertible to the iteration type. In short, the repro above will still result in a conversion error, as with 17.8.

@CyrusNajmabadi
Copy link
Member

@cston

but each element must still be implicitly convertible to the iteration type.

Wait, why is that the case? That would break all sorts of collection-initializable types from being used with collection exprs. I thought that that's exactly what we were addressing just by looking for an "Add" method and no longer caring about convertibility.

@CyrusNajmabadi
Copy link
Member

Reopening, the rule that "element expressions must be convertible to the enumerable element type as #71240 (comment)" is both undesirable and surprising. It goes against hte spirit of the collection-exprs design, and introduces arbitrary limitations that make normal collection-initializable types not work with collection exprs.

@CyrusNajmabadi
Copy link
Member

I do not repro this.

@CyrusNajmabadi CyrusNajmabadi closed this as not planned Won't fix, can't repro, duplicate, stale Nov 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE Feature - Collection Expressions Resolution-By Design The behavior reported in the issue matches the current design
Projects
None yet
Development

No branches or pull requests

7 participants