Skip to content

Handle ternary, switch, and cast expressions in AOT CCW discovery#2480

Open
Sergio0694 wants to merge 3 commits into
masterfrom
user/sergiopedri/fix-aot-analyzer-ternary
Open

Handle ternary, switch, and cast expressions in AOT CCW discovery#2480
Sergio0694 wants to merge 3 commits into
masterfrom
user/sergiopedri/fix-aot-analyzer-ternary

Conversation

@Sergio0694

Copy link
Copy Markdown
Member

Fixes #1947.

Problem

The AOT source generator's CCW lookup table discovery (GetVtableAttributesToAddOnLookupTable in AotOptimizer.cs) called GetTypeInfo directly on the initializer / assignment / return / argument expressions it inspects. For a conditional (ternary) or switch expression, GetTypeInfo only yields the common target type of all branches (typically object or an interface), and for a cast expression it yields the cast target type. So the concrete types actually being boxed or cast were never discovered and got no CCW vtable entries or generic instantiations, failing at runtime under Native AOT.

// Nothing here was discovered: 'List<int>' and 'List<string>' both got no CCW vtable
object obj = GetFlag() ? new List<int>() : (object)new List<string>();

Fix

Add an AddVtableAttributesForExpression helper that looks through parenthesized, cast, conditional (ternary), and switch expressions to reach the concrete leaf expressions that flow into the target, and route every expression-based call site through it. For casts the target type is still processed directly, so existing (List<int>)value discovery is preserved while the operand ((object)new List<string>()) is now also discovered.

Testing

  • Source generator unit tests (src/Tests/SourceGeneratorTest/AotOptimizerTests.cs): run WinRTAotSourceGenerator over ternary, switch, and cast boxing and assert the concrete types are registered in the generated CCW vtable lookup table. The three positive tests fail without the fix and pass with it; a control test guards against discovering types that aren't actually boxed.
  • AOT CCW functional test (src/Tests/FunctionalTests/CCW/Program.cs): box List<T> instances only reachable through a ternary or switch expression and validate, under Native AOT, that their CCWs expose the expected IVector<T> vtable via the reported runtime class name.

Verified locally: SourceGeneratorTest (68 tests) and DiagnosticTests (364 tests) pass, and both the Roslyn 4.8 and Roslyn 4.12 generator variants build cleanly.

Grouped as three commits: the generator fix, the AOT functional test, and the unit tests.

Copilot AI added 3 commits July 2, 2026 14:41
The AOT source generator's CCW lookup table discovery ('GetVtableAttributesToAddOnLookupTable') called 'GetTypeInfo' directly on the initializer / assignment / return / argument expressions. For a conditional (ternary) or switch expression this only yields the common target type (typically 'object' or an interface), and for a cast expression it yields the cast target type, so the concrete branch/operand types being boxed or cast (eg. 'List<int>' in 'object o = flag ? new List<int>() : ...') were never discovered and got no CCW vtable entries or generic instantiations, failing at runtime under Native AOT.

Add an 'AddVtableAttributesForExpression' helper that looks through parenthesized, cast, conditional, and switch expressions to reach the concrete leaf expressions, and route all expression-based call sites through it. For casts the target type is still processed directly to preserve existing '(List<int>)value' detection.

Fixes #1947

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Boxes 'List<T>' instances that are only reachable through a conditional (ternary) or switch expression (mirroring issue #1947) and validates, under Native AOT, that their CCWs expose the expected 'IVector<T>' vtable via the reported runtime class name. Without the generator fix these types get no CCW vtable entries and the runtime class name check fails.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ion discovery

Run the 'WinRTAotSourceGenerator' over conditional (ternary), switch, and cast expressions that box generic types, and assert the discovered concrete types are registered in the generated CCW vtable lookup table. These fail without the generator fix (the boxed types are never discovered) and pass with it, and a control test guards against discovering types that aren't actually boxed. Fixes #1947.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AOT analyzer misses ternary expressions

2 participants