Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unwrap NullableValue for diagnostics creation and add try/catch for formatting diagnostics #110229

Merged
merged 8 commits into from
Jan 6, 2025
9 changes: 9 additions & 0 deletions src/tools/illink/src/ILLink.Shared/Annotations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ private static DynamicallyAccessedMemberTypes[] GetAllDynamicallyAccessedMemberT

public static (DiagnosticId Id, string[] Arguments) GetDiagnosticForAnnotationMismatch (ValueWithDynamicallyAccessedMembers source, ValueWithDynamicallyAccessedMembers target, string missingAnnotations)
{
source = source switch {
// FieldValue and MethodReturnValue have only one diagnostic argument, so formatting throws when the source
// is a NullableValueWithDynamicallyAccessedMembers.
// The correct behavior here is to unwrap always, as the underlying type is the one that has the annotations,
// but it is a breaking change for other UnderlyingTypeValues.
// https://github.com/dotnet/runtime/issues/93800
NullableValueWithDynamicallyAccessedMembers { UnderlyingTypeValue: FieldValue or MethodReturnValue } nullable => nullable.UnderlyingTypeValue,
_ => source
};
DiagnosticId diagnosticId = (source, target) switch {
(MethodParameterValue maybeThisSource, MethodParameterValue maybeThisTarget) when maybeThisSource.IsThisParameter () && maybeThisTarget.IsThisParameter () => DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter,
(MethodParameterValue maybeThis, MethodParameterValue) when maybeThis.IsThisParameter () => DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public static void Main ()
GetUnderlyingTypeOnNonNullableKnownType.Test ();
MakeGenericTypeWithUnknownValue (new object[2] { 1, 2 });
MakeGenericTypeWithKnowAndUnknownArray ();
RequiresOnNullableMakeGenericType.Test();

// Prevents optimizing away 'as Type' conversion.
PreserveSystemType ();
Expand Down Expand Up @@ -100,6 +101,68 @@ static void RequireAllFromMadeGenericNullableOfTypeWithMethodWithRuc ()
typeof (Nullable<>).MakeGenericType (typeof (TestStructWithRucMethod)).RequiresAll ();
}

public class RequiresOnNullableMakeGenericType
{
[Kept]
static Type UnannotatedField;
[Kept]
[KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
static Type FieldWithMethods;
[Kept]
[UnexpectedWarning("IL2080", nameof(UnannotatedField), Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/93800")]
static void Field()
{
typeof (Nullable<>).MakeGenericType (UnannotatedField).GetMethods ();
typeof (Nullable<>).MakeGenericType (FieldWithMethods).GetMethods ();
}

[Kept]
[UnexpectedWarning("IL2090", nameof(unannotated), Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/93800")]
static void Parameter(
Type unannotated,
[KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type annotated)
{
typeof (Nullable<>).MakeGenericType (unannotated).GetMethods ();
typeof (Nullable<>).MakeGenericType (annotated).GetMethods ();
}

[Kept]
[ExpectedWarning("IL2090", "TUnannotated")]
static void TypeParameter<
TUnannotated,
[KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TAnnotated>()
{
typeof (Nullable<>).MakeGenericType (typeof(TUnannotated)).GetMethods ();
typeof (Nullable<>).MakeGenericType (typeof(TAnnotated)).GetMethods ();
}

[Kept]
[UnexpectedWarning("IL2075", nameof(GetUnannotated), Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/93800")]
static void ReturnValue()
{
typeof (Nullable<>).MakeGenericType (GetUnannotated()).GetMethods ();
typeof (Nullable<>).MakeGenericType (GetAnnotated()).GetMethods ();
}
[Kept]
static Type GetUnannotated() => null;
[Kept]
[return: KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
static Type GetAnnotated() => null;

[Kept]
public static void Test()
{
Field();
Parameter(null, null);
TypeParameter<object, object>();
ReturnValue();
}
}

[Kept]
static void TestRequireRucMethodThroughNullable ()
{
Expand Down
Loading