FastExpressionCompiler icon indicating copy to clipboard operation
FastExpressionCompiler copied to clipboard

InvalidProgramException on compiling an expression that returns a record which implements IList

Open TFTomSun opened this issue 3 years ago • 4 comments

I discovered an issue that only appears on linux (the official dotnet sdk docker container)

InvalidProgramException [0]: Common Language Runtime detected an invalid program. at bool (ArrayClosure, MyNotifyA) at Func<R> FastExpressionCompiler.ExpressionCompiler+CurryClosureFuncs.Curry<C, R>(Func<C, R> f, C c)+(T1 t1) => { } at TSource[] System.Linq.Enumerable+WhereEnumerableIterator<TSource>.ToArray() at IReadOnlyListRecord<T> CustomCollectionExtensions.ToReadOnlyRecord<T>(IEnumerable<T> items) at IReadOnlyListRecord<MyNotifyA> (ArrayClosure, NotifyContainer<<>f__AnonymousType1<MyNotifyA, IObservableConcurrentCollection<MyNotifyA>>>)

    internal sealed record ReadOnlyListRecord<T> : IReadOnlyListRecord<T>
    {
        public ReadOnlyListRecord(params T[] items) => Items = items.ToList().AsReadOnly();
        /// <summary>
        /// Gets or initializes the items in this collection.
        /// </summary>
        public IReadOnlyList<T> Items { get; }

        /// <inheritdoc />
        public IEnumerator<T> GetEnumerator()
        {
            return Items.GetEnumerator();
        }

        /// <inheritdoc />
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        /// <inheritdoc />
        public int Count
        {
            get { return Items.Count; }
        }

        /// <inheritdoc />
        public T this[int index] => Items[index];

        /// <inheritdoc />
        public override int GetHashCode()
        {
            int someHashValue = -234897289;
            foreach (var item in Items)
            {
                someHashValue = someHashValue ^ item.GetHashCode();
            }

            return someHashValue;
        }

        /// <inheritdoc />
        public bool Equals(ReadOnlyListRecord<T> other)
        {
            // create a proper equality method...
            if (other == null || other.Count != Count)
            {
                return false;
            }
            for (int i = 0; i < Count; i++)
            {
                if (!other[i].Equals(this[i]))
                {
                    return false;
                }
            }

            return true;
        }
    }

public static class Extensions
{
    public static IReadOnlyListRecord<T> ToReadOnlyRecord<T>(this IEnumerable<T> items) => new ReadOnlyListRecord<T>(items.ToArray());

}

expression

x => x.Value.collectionA.Where(i => i.Number1 % 2 == 0 || x.Value.model.Number2 == 0).ToReadOnlyRecord()

TFTomSun avatar Sep 08 '22 07:09 TFTomSun

What is the FEC version?

dadhi avatar Sep 08 '22 09:09 dadhi

just realized, the same expression fails under net48 with the following exception:

> BadImageFormatException [0]: 
    Throw.OutOfBounds()
    MethodDebugInformationTableReader.GetSequencePoints(MethodDebugInformationHandle handle)
    StackTraceSymbols.GetSourceLineInfoWithoutCasAssert(string assemblyPath, IntPtr loadedPeAddress, int loadedPeSize, IntPtr inMemoryPdbAddress, int inMemoryPdbSize, int methodToken, int ilOffset, out string sourceFile, out int sourceLine, out int sourceColumn)
   

TFTomSun avatar Sep 08 '22 10:09 TFTomSun

I use 3.3.3 ... should be the latest

TFTomSun avatar Sep 08 '22 10:09 TFTomSun

@TFTomSun The late question on the issue, what is the type of x in x => x.Value.collectionA.Where(i => i.Number1 % 2 == 0 || x.Value.model.Number2 == 0).ToReadOnlyRecord() ?

If it is NotifyContainer<<>f__AnonymousType1<MyNotifyA, IObservableConcurrentCollection>, then how it is looking like?

dadhi avatar Oct 01 '22 18:10 dadhi