diff --git a/src/libraries/System.Linq/src/System/Linq/Enumerable.cs b/src/libraries/System.Linq/src/System/Linq/Enumerable.cs index f510f55d7c2b30..8e5571ddda534e 100644 --- a/src/libraries/System.Linq/src/System/Linq/Enumerable.cs +++ b/src/libraries/System.Linq/src/System/Linq/Enumerable.cs @@ -67,8 +67,5 @@ internal static bool TryGetSpan(this IEnumerable source, out R return result; } - - [FeatureSwitchDefinition("System.Linq.Enumerable.ValueTypeTrimFriendlySelect")] - internal static bool ValueTypeTrimFriendlySelect { get; } = AppContext.TryGetSwitch("System.Linq.Enumerable.ValueTypeTrimFriendlySelect", out bool isEnabled) ? isEnabled : false; } } diff --git a/src/libraries/System.Linq/src/System/Linq/OfType.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/OfType.SpeedOpt.cs index f059542b72bd2b..73983cf87fbde8 100644 --- a/src/libraries/System.Linq/src/System/Linq/OfType.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/OfType.SpeedOpt.cs @@ -172,7 +172,7 @@ public override IEnumerable Select(Func s new IEnumerableWhereSelectIterator(objectSource, isTResult, localSelector); } - return new IteratorSelectIterator(this, selector); + return base.Select(selector); } } } diff --git a/src/libraries/System.Linq/src/System/Linq/Select.cs b/src/libraries/System.Linq/src/System/Linq/Select.cs index 4633cd87a2000d..ac27c8dda22eeb 100644 --- a/src/libraries/System.Linq/src/System/Linq/Select.cs +++ b/src/libraries/System.Linq/src/System/Linq/Select.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; using static System.Linq.Utilities; namespace System.Linq @@ -26,7 +25,19 @@ public static IEnumerable Select( if (source is Iterator iterator) { - return SelectImplementation(selector, iterator); + // With native AOT, calling into the `Select` generic virtual method results in NxM + // expansion of native code. If the option is enabled, we don't call the generic virtual + // for value types. We don't do the same for reference types because reference type + // expansion can happen lazily at runtime and the AOT compiler does postpone it (we + // don't need more code, just more data structures describing the new types). + if (IsSizeOptimized && typeof(TResult).IsValueType) + { + return new IEnumerableSelectIterator(iterator, selector); + } + else + { + return iterator.Select(selector); + } } if (source is IList ilist) @@ -52,24 +63,6 @@ public static IEnumerable Select( return new IEnumerableSelectIterator(source, selector); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static IEnumerable SelectImplementation(Func selector, Iterator iterator) - { - // With native AOT, calling into the `Select` generic virtual method results in NxM - // expansion of native code. If the option is enabled, we don't call the generic virtual - // for value types. We don't do the same for reference types because reference type - // expansion can happen lazily at runtime and the AOT compiler does postpone it (we - // don't need more code, just more data structures describing the new types). - if (ValueTypeTrimFriendlySelect && typeof(TResult).IsValueType) - { - if (IsSizeOptimized) - return new IEnumerableSelectIterator(iterator, selector); - return new IteratorSelectIterator(iterator, selector); - } - - return iterator.Select(selector); - } - public static IEnumerable Select(this IEnumerable source, Func selector) { if (source is null) diff --git a/src/libraries/System.Linq/tests/SkipWhileTests.cs b/src/libraries/System.Linq/tests/SkipWhileTests.cs index aa334ed1e50a1b..531cbf1618f2c8 100644 --- a/src/libraries/System.Linq/tests/SkipWhileTests.cs +++ b/src/libraries/System.Linq/tests/SkipWhileTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using Microsoft.DotNet.RemoteExecutor; using Xunit; namespace System.Linq.Tests @@ -61,31 +60,12 @@ public void RunOnce() Assert.Equal(Enumerable.Range(10, 10), Enumerable.Range(0, 20).RunOnce().SkipWhile((i, idx) => idx < 10)); } - [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - public static void SkipErrorWhenSourceErrors_TrimFriendlySelectTrue() - { - RemoteExecutor.Invoke(() => - { - AppContext.SetSwitch("System.Linq.Enumerable.ValueTypeTrimFriendlySelect", true); - - var source = NumberRangeGuaranteedNotCollectionType(-2, 5).Select(i => (decimal)i).Select(m => 1 / m).Skip(4); - var valuesFromEnumerable = source.ToList(); - List expectedValues = [(decimal)1/2]; - Assert.Equal(expectedValues, valuesFromEnumerable); - }).Dispose(); - } - - [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - public void SkipErrorWhenSourceErrors_TrimFriendlySelectFalse() + [Fact] + public void SkipErrorWhenSourceErrors() { - RemoteExecutor.Invoke(() => - { - AppContext.SetSwitch("System.Linq.Enumerable.ValueTypeTrimFriendlySelect", false); - - var source = NumberRangeGuaranteedNotCollectionType(-2, 5).Select(i => (decimal)i).Select(m => 1 / m).Skip(4); - using var en = source.GetEnumerator(); - Assert.Throws(() => en.MoveNext()); - }).Dispose(); + var source = NumberRangeGuaranteedNotCollectionType(-2, 5).Select(i => (decimal)i).Select(m => 1 / m).Skip(4); + using var en = source.GetEnumerator(); + Assert.Throws(() => en.MoveNext()); } [Fact] diff --git a/src/libraries/System.Linq/tests/System.Linq.Tests.csproj b/src/libraries/System.Linq/tests/System.Linq.Tests.csproj index b45d94707e15cc..2e1ad5368b276b 100644 --- a/src/libraries/System.Linq/tests/System.Linq.Tests.csproj +++ b/src/libraries/System.Linq/tests/System.Linq.Tests.csproj @@ -1,6 +1,5 @@ - true $(NetCoreAppCurrent) true