Skip to content

Add regression tests for generic type parameter reflection properties#125581

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/fix-stackoverflowexception-unbound-generic-types
Draft

Add regression tests for generic type parameter reflection properties#125581
Copilot wants to merge 2 commits intomainfrom
copilot/fix-stackoverflowexception-unbound-generic-types

Conversation

Copy link
Contributor

Copilot AI commented Mar 15, 2026

Summary

Adds regression tests to verify the correct behavior of reflection properties for generic type parameters (e.g., T from List<T>), specifically addressing the scenario described in the issue where processing unbound generic types like typeof(List<>) through reflection can lead to StackOverflowException.

Root Cause Analysis

The reported StackOverflowException is not a runtime bug. It is caused by user code that recursively walks both Type.DeclaringType and Type.GetGenericArguments() without checking Type.IsGenericParameter, creating an infinite cycle:

  1. typeof(List<>).GetGenericArguments() returns [T] (the type parameter)
  2. T.DeclaringType returns typeof(List<>) (the declaring generic type definition)
  3. Processing typeof(List<>) again leads back to step 1 → infinite recursion

This circular reference between DeclaringType and GetGenericArguments() is by design. The correct pattern is to check type.IsGenericParameter before recursing through DeclaringType, as demonstrated in the runtime's own TypeNameBuilder.cs:

for (Type? t = rootType; t != null; t = t.IsGenericParameter ? null : t.DeclaringType)

Changes

Added two test methods to TypeTests.cs:

  • GenericTypeParameter_Properties (Theory with 6 cases): Verifies that generic type parameters correctly report IsGenericType=false, IsGenericParameter=true, FullName=null, expected Name, and correct DeclaringType for parameters from List<>, Dictionary<,>, Outside<>, and Outside<>.Inside<>.

  • GenericTypeDefinition_GetGenericArguments_DeclaringTypeCycle: Documents and verifies the by-design circular reference between DeclaringType and GetGenericArguments() for both single-parameter (List<>) and multi-parameter (Dictionary<,>) generic type definitions.

Test Results

All 7 new tests pass. Full test suite (68,089 tests) passes with 0 failures.

Copilot AI and others added 2 commits March 15, 2026 14:39
Add tests to verify that generic type parameters (e.g., T from List<T>)
correctly report IsGenericType=false, IsGenericParameter=true,
FullName=null, and that DeclaringType correctly points back to the
generic type definition. These tests document the by-design circular
reference between DeclaringType and GetGenericArguments() that user code
must handle by checking IsGenericParameter.

Addresses dotnet/runtime#XXXXX - the reported StackOverflowException is
caused by user code that recursively walks both DeclaringType and
GetGenericArguments() without checking IsGenericParameter, not by a
runtime bug.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

StackOverflowException with Unbound Generic Types and ArgumentNullException in Reflection Context

2 participants