diff --git a/src/WinRT.Runtime/ApiCompatBaseline.txt b/src/WinRT.Runtime/ApiCompatBaseline.txt
index c7584cc04..dcf5bea51 100644
--- a/src/WinRT.Runtime/ApiCompatBaseline.txt
+++ b/src/WinRT.Runtime/ApiCompatBaseline.txt
@@ -21,4 +21,5 @@ CannotRemoveAttribute : Attribute 'WinRT.ObjectReferenceWrapperAttribute' exists
CannotRemoveAttribute : Attribute 'WinRT.ObjectReferenceWrapperAttribute' exists on 'WinRT.IInspectable' in the contract but not the implementation.
MembersMustExist : Member 'protected void Microsoft.UI.Xaml.LayoutCycleException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'protected void Microsoft.UI.Xaml.Automation.ElementNotAvailableException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
-Total Issues: 122
+CannotChangeAttribute : Attribute 'System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute' on 'WinRT.WindowsRuntimeHelperTypeAttribute.HelperType' changed from '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes)]' in the contract to '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)]' in the implementation.
+Total Issues: 123
diff --git a/src/WinRT.Runtime/AttributeMessages.net5.cs b/src/WinRT.Runtime/AttributeMessages.net5.cs
index 91dc012ae..04eda9fa3 100644
--- a/src/WinRT.Runtime/AttributeMessages.net5.cs
+++ b/src/WinRT.Runtime/AttributeMessages.net5.cs
@@ -10,6 +10,11 @@ internal static class AttributeMessages
///
public const string GenericDeprecatedMessage = "This method is deprecated and will be removed in a future release.";
+ ///
+ /// Message for a generic annotation for a method using .
+ ///
+ public const string GenericRequiresUnreferencedCodeMessage = "This method is not trim-safe, and is only supported for use when not using trimming (or AOT).";
+
///
/// Message for marshalling or generic code requiring .
///
diff --git a/src/WinRT.Runtime/Attributes.cs b/src/WinRT.Runtime/Attributes.cs
index 2d332a5cb..be07a166e 100644
--- a/src/WinRT.Runtime/Attributes.cs
+++ b/src/WinRT.Runtime/Attributes.cs
@@ -97,7 +97,7 @@ public WindowsRuntimeHelperTypeAttribute()
public WindowsRuntimeHelperTypeAttribute(
#if NET
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)]
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type helperType)
{
@@ -105,7 +105,7 @@ public WindowsRuntimeHelperTypeAttribute(
}
#if NET
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)]
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)]
#endif
public Type HelperType { get; }
}
diff --git a/src/WinRT.Runtime/ComWrappersSupport.cs b/src/WinRT.Runtime/ComWrappersSupport.cs
index f805baa28..8bbda9a01 100644
--- a/src/WinRT.Runtime/ComWrappersSupport.cs
+++ b/src/WinRT.Runtime/ComWrappersSupport.cs
@@ -159,7 +159,6 @@ public static void RegisterHelperType(
Type type,
#if NET
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type helperType) => TypeExtensions.HelperTypeCache.TryAdd(type, helperType);
diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs
index 88904706e..7ef7247ad 100644
--- a/src/WinRT.Runtime/Marshalers.cs
+++ b/src/WinRT.Runtime/Marshalers.cs
@@ -1375,7 +1375,6 @@ struct MarshalInterface
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicFields |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicMethods)]
#endif
private static Type _HelperType;
@@ -1383,7 +1382,6 @@ struct MarshalInterface
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicFields |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicMethods)]
#endif
private static Type HelperType => _HelperType ??= typeof(T).GetHelperType();
diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt
index 93601c34a..8079ba1ea 100644
--- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt
+++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt
@@ -215,4 +215,6 @@ TypesMustExist : Type 'ABI.WinRT.Interop.EventSource' does not exist
TypesMustExist : Type 'ABI.WinRT.Interop.EventSourceState' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'ABI.WinRT.Interop.EventHandlerEventSource' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'ABI.WinRT.Interop.EventHandlerEventSource' does not exist in the reference but it does exist in the implementation.
-Total Issues: 217
+CannotChangeAttribute : Attribute 'System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute' on 'WinRT.WindowsRuntimeHelperTypeAttribute.HelperType' changed from '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)]' in the implementation to '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes)]' in the reference.
+CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute' exists on 'WinRT.TypeExtensions.FindVftblType(System.Type)' in the implementation but not the reference.
+Total Issues: 219
diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs
index 96a68f684..66de64b61 100644
--- a/src/WinRT.Runtime/Projections.cs
+++ b/src/WinRT.Runtime/Projections.cs
@@ -120,7 +120,6 @@ private static void RegisterCustomAbiTypeMapping(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type abiType,
@@ -143,7 +142,6 @@ private static void RegisterCustomTypeToHelperTypeMapping(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type helperType)
@@ -164,7 +162,6 @@ private static void RegisterCustomTypeToHelperTypeMappingNoLock(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type helperType)
@@ -177,7 +174,6 @@ private static void RegisterCustomAbiTypeMappingNoLock(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type abiType,
@@ -200,7 +196,6 @@ private static void RegisterCustomAbiTypeMapping(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type abiType)
@@ -221,7 +216,6 @@ private static void RegisterCustomAbiTypeMappingNoLock(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type abiType)
@@ -233,7 +227,6 @@ private static void RegisterCustomAbiTypeMappingNoLock(
#if NET
[return: DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
public static Type FindCustomHelperTypeMapping(Type publicType, bool filterToRuntimeClass = false)
diff --git a/src/WinRT.Runtime/TypeExtensions.cs b/src/WinRT.Runtime/TypeExtensions.cs
index 2cd70aa5f..def3b4f2f 100644
--- a/src/WinRT.Runtime/TypeExtensions.cs
+++ b/src/WinRT.Runtime/TypeExtensions.cs
@@ -21,7 +21,6 @@ static class TypeExtensions
#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
[SuppressMessage("Trimming", "IL2073", Justification = "Matching trimming annotations are used at all callsites registering helper types present in the cache.")]
#endif
@@ -29,7 +28,6 @@ public static Type FindHelperType(this Type type)
{
#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
static Type FindHelperTypeNoCache(Type type)
@@ -76,7 +74,7 @@ static Type FindHelperTypeNoCache(Type type)
#if NET
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "No members of the generic type are dynamically accessed other than for the attributes on it.")]
- [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)]
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)]
#endif
static Type GetHelperTypeFromAttribute(WindowsRuntimeHelperTypeAttribute helperTypeAtribute, Type type)
{
@@ -119,8 +117,7 @@ static Type FindHelperTypeFallback(Type type)
}
#if NET
- [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
- DynamicallyAccessedMemberTypes.PublicNestedTypes |
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
public static Type GetHelperType(this Type type)
@@ -140,13 +137,10 @@ public static Type GetGuidType(this Type type)
}
#if NET
- [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
-#endif
- public static Type FindVftblType(
-#if NET
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+ [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "The fallback path is not AOT-safe by design (to avoid annotations).")]
+ [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The fallback path is not trim-safe by design (to avoid annotations).")]
#endif
- this Type helperType)
+ public static Type FindVftblType(this Type helperType)
{
#if NET
if (!RuntimeFeature.IsDynamicCodeCompiled)
@@ -155,23 +149,49 @@ public static Type FindVftblType(
}
#endif
- Type vftblType = helperType.GetNestedType("Vftbl");
- if (vftblType is null)
- {
- return null;
- }
- if (helperType.IsGenericType && vftblType is object)
+#if NET8_0_OR_GREATER
+ [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)]
+#endif
+#if NET
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.IAsyncActionWithProgress`1+Vftbl", "Microsoft.Windows.SDK.NET")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.IAsyncOperationWithProgress`2+Vftbl", "Microsoft.Windows.SDK.NET")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.IAsyncOperation`1+Vftbl", "Microsoft.Windows.SDK.NET")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.Collections.IMapChangedEventArgs`1+Vftbl", "Microsoft.Windows.SDK.NET")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.Collections.IObservableMap`2+Vftbl", "Microsoft.Windows.SDK.NET")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.Collections.IObservableVector`1+Vftbl", "Microsoft.Windows.SDK.NET")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.EventHandler`1+Vftbl", "WinRT.Runtime")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.KeyValuePair`2+Vftbl", "WinRT.Runtime")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IEnumerable`1+Vftbl", "WinRT.Runtime")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IEnumerator`1+Vftbl", "WinRT.Runtime")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IList`1+Vftbl", "WinRT.Runtime")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IReadOnlyList`1+Vftbl", "WinRT.Runtime")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IDictionary`2+Vftbl", "WinRT.Runtime")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IReadOnlyDictionary`2+Vftbl", "WinRT.Runtime")]
+ [RequiresUnreferencedCode(AttributeMessages.GenericRequiresUnreferencedCodeMessage)]
+#endif
+ static Type FindVftblTypeFallback(Type helperType)
{
-#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273
- vftblType = vftblType.MakeGenericType(helperType.GetGenericArguments());
-#pragma warning restore IL3050
+ Type vftblType = helperType.GetNestedType("Vftbl");
+ if (vftblType is null)
+ {
+ return null;
+ }
+ if (helperType.IsGenericType)
+ {
+ vftblType = vftblType.MakeGenericType(helperType.GetGenericArguments());
+ }
+ return vftblType;
}
- return vftblType;
+
+ return FindVftblTypeFallback(helperType);
}
+#if NET
+ [SuppressMessage("Trimming", "IL2075", Justification = "The path using vtable types is a fallback and is not trim-safe by design.")]
+#endif
internal static IntPtr GetAbiToProjectionVftblPtr(
#if NET
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
#endif
this Type helperType)
{