Skip to content

Commit 2dc7174

Browse files
Expand description of generic recursions (#36303)
Addresses dotnet/runtime#85184 (comment).
1 parent 480a202 commit 2dc7174

File tree

1 file changed

+21
-0
lines changed
  • docs/core/deploying/native-aot/warnings

1 file changed

+21
-0
lines changed

docs/core/deploying/native-aot/warnings/il3054.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ When the AOT compilation process detects such unbounded growth, it cuts off the
2020

2121
Even though it's unlikely the throwing method body will be reached at run time, it's advisable to remove the generic recursion by restructuring the code. Generic recursion negatively affects compilation speed and the size of the output executable.
2222

23+
In .NET, generic code instantiated over reference type is shared across all reference typed instantiations (for example, the code to support `List<string>` and `List<object>` is the same). However, additional native data structures are needed to express the "generic context" (the thing that gets substituted for `T`). It is possible to form generic recursion within these data structures as well. For example, this can happen if the generic context for `Foo<T>` needs to refer to `Foo<Foo<T>>` that in turn needs `Foo<Foo<Foo<T>>>`.
24+
2325
## Example
2426

2527
The following program will work correctly for input "2" but throws an exception for input "100".
@@ -56,3 +58,22 @@ Unhandled Exception: System.TypeLoadException: Could not load type 'Program' fro
5658
at Program.<<Main>$>g__CauseGenericRecursion|0_0[T](Int32) + 0x1f
5759
at Program.<Main>$(String[]) + 0x3a
5860
```
61+
62+
Similarly, the following program causes recursion within native data structures (as opposed to generic recursion within native code), since the instantiation is over a reference type, but has a cycle:
63+
64+
```csharp
65+
// AOT analysis warning IL3054:
66+
// Program.<<Main>$>g__Recursive|0_0<List`1<List`1<List`1<List`1<Object>>>>>():
67+
// Generic expansion to 'Program.<<Main>$>g__Recursive|0_0<List`1<List`1<List`1<List`1<List`1<Object>>>>>>()'
68+
// was aborted due to generic recursion. An exception will be thrown at runtime if this codepath
69+
// is ever reached. Generic recursion also negatively affects compilation speed and the size of
70+
// the compilation output. It is advisable to remove the source of the generic recursion
71+
// by restructuring the program around the source of recursion. The source of generic recursion
72+
// might include: 'Program.<<Main>$>g__Recursive|0_0<T>()'
73+
74+
using System.Collections.Generic;
75+
76+
Recursive<object>();
77+
78+
static void Recursive<T>() => Recursive<List<T>>();
79+
```

0 commit comments

Comments
 (0)