-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
.NET 9 Preview.5
, Preview.6
, Preview.7
C# compiler crashes on LINQ expression with string interpolation
#74163
Comments
Preview.5
, Preview.6
, Preview.7
crashes on LINQ expression with string interpolation
Preview.5
, Preview.6
, Preview.7
crashes on LINQ expression with string interpolationPreview.5
, Preview.6
, Preview.7
C# compiler crashes on LINQ expression with string interpolation
The string interpolation is handled internally as collection-expression conversion to a readonly span (a debug assert is also triggered). Currently: using System.Collections.Generic;
using System.Linq;
class Program
{
static IQueryable<string> GetStrings() => null;
public static void Main() =>
GetStrings().Select(o => string.Format("{0} {1} {2} {3}", o, o, o, o));
} For expression trees we could lower it to (no ref struct allowed): using System.Collections.Generic;
using System.Linq;
class Program
{
static IQueryable<string> GetStrings() => null;
public static void Main() =>
GetStrings().Select(o => string.Format("{0} {1} {2} {3}", new object[] { o, o, o, o }));
} But it would be maybe better to handle it in the invocation binding. |
It sounds like a usage of a non-array params collection is making its way to an expression tree without triggering an error.
The following method is supposed to detect the situation:
At the moment there is no clarity how exactly a collection expression is getting through. Understanding that should be the next step in instigation of this issue. |
Could you please provide more details?
Where exactly this handling is happening?
What does assert check? Where it is in the code? What the call stack looks like? |
The collection-conversion comes to play at (here we lower and assume overload resolution to pick the right one): roslyn/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringInterpolation.cs Line 354 in 3a3c108
This is great because we have multiple overloads, with and without params. Overload resolution chooses the best one. And this allows the same code for less than 4 parameters, too. The problem arises now for the params overload because we have 2 of them and the span overload is better.
It is here roslyn/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_CollectionExpression.cs Line 34 in 3a3c108
The callstack is:
|
Well, as we can see this approach is fragile and/or lacks proper validation of the result that it produces. |
Other parts of |
I think it would be good to understand what overloads roslyn/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringInterpolation.cs Line 354 in 3a3c108
|
More detailed call stack for the following scenario:
Call stack:
|
Here is a unit-test that hits the same exception once all debug asserts on the way are disabled:
|
…not use expanded non-array `params` collection in Format/Create calls. Fixes dotnet#74163.
Version Used:
.NET 9 SDK 9.0.100-preview.5.24307.3
tried also Preview.6 and today's Preview.7
Steps to Reproduce:
Following code:
with
.csproj
:Diagnostic Id:
Expected Behavior:
Successful build
Actual Behavior:
Compiler crash
(does work without
<LangVersion>Preview</LangVersion>
setting)The text was updated successfully, but these errors were encountered: