This project is read-only.

GetQueryClauseInfo has incorrect CastInfo for simple select-many query using IQueryable


An explicit type in any "from" clause should induce a Cast call on the collection expression in the clause. The symbol associated with this call should be returned by a call to GetQueryClauseInfo. Oddly enough, this is done correctly if the collection expression is IEnumerable<object> but NOT if it is IQueryable<object>, and it fails on the second from clause but not the first.

A program will make it more clear.
using System;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace EricLippertScratch
    class Program
        static void Main(string[] args)
            const string sourceText = @"
using System.Linq;
using System.Collections.Generic;
class C
    static IEnumerable<object> M(int q) { return null; }
    void M(IEnumerable<object> seq)
        var r = from int x in seq
                from int y in M(x)
                select x + y;

    static IQueryable<object> N(int q) { return null; }
    void M(IQueryable<object> seq)
        var r = from int x in seq
                from int y in N(x)
                select x + y;

            var references =
                .Select(type => new MetadataFileReference(
                    fullPath: type.Assembly.Location,
                    kind: MetadataImageKind.Assembly,
                    alias: null,
                    embedInteropTypes: false))

            var tree = SyntaxFactory.ParseSyntaxTree(sourceText, "fileName", CSharpParseOptions.Default);

            var compilation = CSharpCompilation.Create(
                assemblyName: "outputFile",
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
                syntaxTrees: new[] { tree },
                references: references);

            var model = compilation.GetSemanticModel(tree);

            var diagnostics = compilation.GetDiagnostics();

            var clauses = tree

            var casts = clauses
                .Select(clause => model.GetQueryClauseInfo(clause).CastInfo.Symbol)

            foreach(var cast in casts)
                Console.WriteLine(cast != null);
Expected output: true true true true
Observed output: true true true false

I have not yet debugged into the analyzer to figure out what is going wrong here.