Skip to content

Commit f860bce

Browse files
[release/6.0] Set generic type arguments nullability for value types (#58390)
* Set generic type arguments nullability for value types * Skip test on mono * Apply commment * Separate var name parts with _ * Reflection nullability API: improve test coverage, fix bug found (#58479) * Add/remove some tests, fix generics indexing bug Co-authored-by: Buyaa Namnan <[email protected]>
1 parent 9e5a932 commit f860bce

File tree

2 files changed

+217
-52
lines changed

2 files changed

+217
-52
lines changed

src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfoContext.cs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -347,19 +347,23 @@ private NullabilityInfo GetNullabilityInfo(MemberInfo memberInfo, Type type, ILi
347347
private NullabilityInfo GetNullabilityInfo(MemberInfo memberInfo, Type type, IList<CustomAttributeData> customAttributes, int index)
348348
{
349349
NullabilityState state = NullabilityState.Unknown;
350+
NullabilityInfo? elementState = null;
351+
NullabilityInfo[] genericArgumentsState = Array.Empty<NullabilityInfo>();
352+
Type? underlyingType = type;
350353

351354
if (type.IsValueType)
352355
{
353-
if (Nullable.GetUnderlyingType(type) != null)
356+
underlyingType = Nullable.GetUnderlyingType(type);
357+
358+
if (underlyingType != null)
354359
{
355360
state = NullabilityState.Nullable;
356361
}
357362
else
358363
{
364+
underlyingType = type;
359365
state = NullabilityState.NotNull;
360366
}
361-
362-
return new NullabilityInfo(type, state, state, null, Array.Empty<NullabilityInfo>());
363367
}
364368
else
365369
{
@@ -368,32 +372,38 @@ private NullabilityInfo GetNullabilityInfo(MemberInfo memberInfo, Type type, ILi
368372
state = GetNullableContext(memberInfo);
369373
}
370374

371-
NullabilityInfo? elementState = null;
372-
NullabilityInfo[]? genericArgumentsState = null;
373-
374375
if (type.IsArray)
375376
{
376377
elementState = GetNullabilityInfo(memberInfo, type.GetElementType()!, customAttributes, index + 1);
377378
}
378-
else if (type.IsGenericType)
379+
}
380+
381+
if (underlyingType.IsGenericType)
382+
{
383+
Type[] genericArguments = underlyingType.GetGenericArguments();
384+
genericArgumentsState = new NullabilityInfo[genericArguments.Length];
385+
386+
for (int i = 0, offset = 0; i < genericArguments.Length; i++)
379387
{
380-
Type[] genericArguments = type.GetGenericArguments();
381-
genericArgumentsState = new NullabilityInfo[genericArguments.Length];
388+
Type t = Nullable.GetUnderlyingType(genericArguments[i]) ?? genericArguments[i];
382389

383-
for (int i = 0; i < genericArguments.Length; i++)
390+
if (!t.IsValueType || t.IsGenericType)
384391
{
385-
genericArgumentsState[i] = GetNullabilityInfo(memberInfo, genericArguments[i], customAttributes, i + 1);
392+
offset++;
386393
}
387-
}
388394

389-
NullabilityInfo nullability = new NullabilityInfo(type, state, state, elementState, genericArgumentsState ?? Array.Empty<NullabilityInfo>());
390-
if (state != NullabilityState.Unknown)
391-
{
392-
TryLoadGenericMetaTypeNullability(memberInfo, nullability);
395+
genericArgumentsState[i] = GetNullabilityInfo(memberInfo, genericArguments[i], customAttributes, index + offset);
393396
}
397+
}
398+
399+
NullabilityInfo nullability = new NullabilityInfo(type, state, state, elementState, genericArgumentsState);
394400

395-
return nullability;
401+
if (!type.IsValueType && state != NullabilityState.Unknown)
402+
{
403+
TryLoadGenericMetaTypeNullability(memberInfo, nullability);
396404
}
405+
406+
return nullability;
397407
}
398408

399409
private static bool ParseNullableState(IList<CustomAttributeData> customAttributes, int index, ref NullabilityState state)
@@ -472,7 +482,7 @@ private void CheckGenericParameters(NullabilityInfo nullability, MemberInfo meta
472482
{
473483
NullabilityState state = nullability.ReadState;
474484

475-
if (!ParseNullableState(metaType.GetCustomAttributesData(), 0, ref state))
485+
if (state == NullabilityState.NotNull && !ParseNullableState(metaType.GetCustomAttributesData(), 0, ref state))
476486
{
477487
state = GetNullableContext(metaType);
478488
}

0 commit comments

Comments
 (0)