Skip to content

Commit

Permalink
Use manual foreach instead of AddRange method for certain collect…
Browse files Browse the repository at this point in the history
…ion expression spreads (#74630)

* Use manual `foreach` instead of `AddRange` method when collection type of spreading element doesn't implement `ICollection<T>`, but has a `struct` enumerator
  • Loading branch information
DoctorKrolic authored Aug 14, 2024
1 parent 74270d4 commit e1496f4
Show file tree
Hide file tree
Showing 2 changed files with 578 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,21 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty
if (addRangeMethod is null)
return false;

if (spreadElement.EnumeratorInfoOpt is { } enumeratorInfo)
{
var iCollectionOfTType = _compilation.GetSpecialType(SpecialType.System_Collections_Generic_ICollection_T);
var iCollectionOfElementType = iCollectionOfTType.Construct(enumeratorInfo.ElementType);
var discardedUseSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;

// If collection has a struct enumerator but doesn't implement ICollection<T>
// then manual `foreach` is always more efficient then using `AddRange` method
if (enumeratorInfo.GetEnumeratorInfo.Method.ReturnType.IsValueType &&
!enumeratorInfo.CollectionType.ImplementsInterface(iCollectionOfElementType, ref discardedUseSiteInfo))
{
return false;
}
}

var type = rewrittenSpreadOperand.Type!;

var useSiteInfo = GetNewCompoundUseSiteInfo();
Expand Down
Loading

0 comments on commit e1496f4

Please sign in to comment.