Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Use manual foreach instead of AddRange method for certain collection expression spreads #74630

Merged
merged 9 commits into from
Aug 14, 2024
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