Skip to content

Collection expression loophole: ability to invoke .Add() method with the parameter type not matching the collection expression element type #7724

@controlflow

Description

@controlflow

Version Used: main branch

Steps to Reproduce:

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

BadCandidateForCollectionExpression xs = [123]; // no .Add(int)
BadCandidateForCollectionExpression ys = ["abc"]; // not int element type
BadCandidateForCollectionExpression zs = [default]; // ????

class BadCandidateForCollectionExpression : IEnumerable<int>
{
  public void Add(string s) { }

  IEnumerator<int> IEnumerable<int>.GetEnumerator() { yield break; }
  IEnumerator IEnumerable.GetEnumerator() { yield break; }
}

Expected Behavior:

Impossible to fill the collection expression, no Add method can accept the value of int type - the element type inferred as a collection expression element type.

Actual Behavior:

If the expression is both convertible to inferred element type and can be accepted by some non-int Add method overload - it compiles successfully.
As the result you have a really weird language context - you can only pass expressions that are implicitly convertible to int, but the invoked method accepts string value.

I guess this is the poorly written check in frontend, I guess instead of checking the element expression to be convertible to int you probably must check the parameter type of invoked .Add() method to have type convertible to int.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions