Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/core/deploying/native-aot/warnings/il3054.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ When the AOT compilation process detects such unbounded growth, it cuts off the

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.

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>>>`.

## Example

The following program will work correctly for input "2" but throws an exception for input "100".
Expand Down Expand Up @@ -56,3 +58,22 @@ Unhandled Exception: System.TypeLoadException: Could not load type 'Program' fro
at Program.<<Main>$>g__CauseGenericRecursion|0_0[T](Int32) + 0x1f
at Program.<Main>$(String[]) + 0x3a
```

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:

```csharp
// AOT analysis warning IL3054:
// Program.<<Main>$>g__Recursive|0_0<List`1<List`1<List`1<List`1<Object>>>>>():
// Generic expansion to 'Program.<<Main>$>g__Recursive|0_0<List`1<List`1<List`1<List`1<List`1<Object>>>>>>()'
// was aborted due to generic recursion. An exception will be thrown at runtime if this codepath
// is ever reached. Generic recursion also negatively affects compilation speed and the size of
// the compilation output. It is advisable to remove the source of the generic recursion
// by restructuring the program around the source of recursion. The source of generic recursion
// might include: 'Program.<<Main>$>g__Recursive|0_0<T>()'

using System.Collections.Generic;

Recursive<object>();

static void Recursive<T>() => Recursive<List<T>>();
```