Skip to content

InvalidProgramException when accessing struct IReadOnlyList<T> in Expression<T> #41674

Closed
@chrarnoldus

Description

@chrarnoldus

Description

The code included below crashes with the following exception:

Unhandled exception. System.InvalidProgramException: Common Language Runtime detected an invalid program.
   at ConsoleApp1.Program.Main(String[] args)

I expected the code to do nothing at all, since I am not even evaluating the IQueryable.

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

namespace ConsoleApp1
{
    internal struct ReadOnlyList<T> : IReadOnlyList<T>
    {
        public int Count
            => throw new Exception();

        public T this[int index]
            => throw new Exception();

        public IEnumerator<T> GetEnumerator()
        {
            throw new Exception();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

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

    internal class Program
    {
        private static void Main(string[] args)
        {
            var list = default(ReadOnlyList<string>);
            var unused = Array.Empty<int>()
                .AsQueryable()
                .Select(x => list[x]);
        }
    }
}

Configuration

.NET SDK (reflecting any global.json):
Version: 5.0.100-preview.8.20417.9
Commit: fc62663a35

Runtime Environment:
OS Name: Windows
OS Version: 10.0.19041
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.100-preview.8.20417.9\

Host (useful for support):
Version: 5.0.0-preview.8.20407.11
Commit: bf45665

Regression?

Yes, compared to 3.1.

Other information

  • Replacing the implemented interface IReadOnlyList<T> with IEnumerable<T> resolves the crash.
  • Replacing the type argument of ReadOnlyList<string> with a value type resolves the crash.
  • Turning the struct ReadOnlyList<T> into a class resolves the crash.
  • The code where I originally discovered the issue did not use IQueryable, but a custom method accepting Expression<T>.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions