Convert AOT/trim pragma suppressions to attributes so they propagate to consumers#8686
Merged
Evangelink merged 3 commits intoMay 31, 2026
Conversation
…to consumers #pragma warning disable IL2xxx/IL3xxx only silences C# compile-time warnings; it does not affect ILC analyzer warnings at downstream consumers' publish time. Convert MSTest's existing pragma suppressions into attribute-based suppressions (UnconditionalSuppressMessage / RequiresUnreferencedCode / RequiresDynamicCode) that survive into IL and are honored by ILC. This is motivated by microsoft#8586 which switches the NativeAOT integration test to reference MSTest.TestAdapter, surfacing all of MSTest's previously-pragma'd warnings as errors. This change addresses ~31 of those warnings independently of microsoft#8586. Out of scope (future work): warnings from vstest's Microsoft.TestPlatform.ObjectModel (submodule), the MSTestSourceGeneratedReflectionMetadata.g.cs IL2070 (belongs in microsoft#8586's generator emitter), and transitive DataContract warnings inside System.Private.DataContractSerialization. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates MSTest/TestAdapter code to ensure existing ILLink/NativeAOT/single-file warning suppressions propagate to downstream consumers by converting #pragma warning disable ILxxxx suppressions into attribute-based suppressions (e.g., [UnconditionalSuppressMessage], [RequiresUnreferencedCode], [RequiresDynamicCode]) that are preserved in emitted IL.
Changes:
- Convert IL3000 (single-file
Assembly.Location) pragma suppressions to[UnconditionalSuppressMessage]in adapter/bridge paths. - Convert reflection/trimming/AOT-related pragma suppressions (IL2026/IL2057/IL2060/IL2067/IL2070/IL2072/IL3050) to per-member attribute suppressions in reflection-heavy helpers/services.
- Refactor
DataSerializationHelperserializer-cache lambdas into named methods so suppressions attach to the analyzer-reported call sites.
Show a summary per file
| File | Description |
|---|---|
| src/TestFramework/TestFramework/Internal/ReflectionTestMethodInfo.cs | Adds Requires* attributes to MakeGenericMethod override (guarded by TFM) so downstream trimming/AOT analyzers see the annotations. |
| src/Platform/Microsoft.Testing.Extensions.VSTestBridge/SynchronizedSingleSessionVSTestAndTestAnywhereAdapter.cs | Replaces IL3000 pragmas with an attribute on GetAssemblyPath so single-file suppression survives into consumer publish. |
| src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtilityBase.cs | Adds IL3000 suppression attribute to deployment path and removes localized pragma usage. |
| src/Adapter/MSTestAdapter.PlatformServices/TestMethodFilter.cs | Adds IL2072 suppression attribute for reflection-based VSTest discovery-context filter extraction. |
| src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs | Adds IL3000 suppression attribute to resolution-path logic and removes pragmas. |
| src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs | Replaces broad pragma block with targeted per-method suppression attributes for trimming/reflection warnings. |
| src/Adapter/MSTestAdapter.PlatformServices/Helpers/ManagedNameHelper.cs | Adds per-method suppression attributes for reflection-based managed-name lookup. |
| src/Adapter/MSTestAdapter.PlatformServices/Helpers/DataSerializationHelper.cs | Adds IL2026/IL3050 suppressions and extracts serializer factories into named methods so suppressions apply correctly. |
| src/Adapter/MSTestAdapter.PlatformServices/Extensions/MethodInfoExtensions.cs | Adds IL2060/IL3050 suppression attributes to generic-method construction helper. |
| src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs | Adds IL2026 suppression attribute to LoadAssemblyFrom and removes pragma wrapper. |
Copilot's findings
- Files reviewed: 10/10 changed files
- Comments generated: 0
Adds Publish_WithTestAdapter_DoesNotSurfaceWarningsFromSuppressedSources to MSTest.Acceptance.IntegrationTests/TrimTests.cs. Publishes a small project that references MSTest.TestAdapter with PublishTrimmed=true and TrimmerRootAssembly forcing trim analysis of MSTestAdapter.PlatformServices, Microsoft.Testing.Extensions.VSTestBridge, and MSTest.TestFramework. Asserts that the source files we suppressed in this PR no longer appear in publish output (the IL trimmer includes source paths in its warnings, so absence == suppression worked). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…FromSuppressedSources DotnetCli.RunAsync defaults warnAsError to true, which auto-injects -p:MSBuildTreatWarningsAsErrors=true -p:TreatWarningsAsErrors=true into the publish command. The acceptance test for this PR was written assuming TreatWarningsAsErrors is OFF (so out-of-repo trim warnings from the vstest ObjectModel submodule and App Insights stay as warnings, and the test can grep the publish output for the absence of suppressed source file names). Without this fix the publish fails with NETSDK1144 (Optimizing assemblies for size failed) due to dozens of trim warnings that are explicitly out of scope for this PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
PR #8586 enables a Native AOT integration test that exercises
MSTest.TestAdapter. When that test publishes withPublishAot=true+MSBuildTreatWarningsAsErrors=true+TrimmerSingleWarn=false, the ILC trim/AOT analyzer surfaces every individual warning from MSTest's libraries as an error.Many of those warnings are already suppressed in source via
#pragma warning disable ILxxxx— but the C##pragmaonly silences the compile-time warning. It has no effect on the linker/ILC analyzer warnings that fire at a downstream consumer's publish time. To silence those, suppressions must be expressed as attributes ([UnconditionalSuppressMessage],[RequiresUnreferencedCode],[RequiresDynamicCode]) that survive into the IL where ILC can see them.This PR is a focused mechanical conversion of MSTest's existing
ILpragmas to attribute form, addressing ~31 of the warnings #8586 currently surfaces. It is independent of #8586 and can land first.Changes (product code)
TestFramework/Internal/ReflectionTestMethodInfo.cs[RequiresUnreferencedCode](NET5+) and[RequiresDynamicCode](NET7+) on theMakeGenericMethodoverride to match the base member's annotations (fixes IL2046 / IL3051)MSTestAdapter.PlatformServices/Services/TestSourceHost.cs[UnconditionalSuppressMessage("SingleFile", "IL3000")]onGetResolutionPathsMSTestAdapter.PlatformServices/Utilities/DeploymentUtilityBase.csDeployPlatform/Microsoft.Testing.Extensions.VSTestBridge/SynchronizedSingleSessionVSTestAndTestAnywhereAdapter.csGetAssemblyPathMSTestAdapter.PlatformServices/AssemblyResolver.cs[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026")]onLoadAssemblyFromMSTestAdapter.PlatformServices/Services/ReflectionOperations.csMSTestAdapter.PlatformServices/Helpers/DataSerializationHelper.cs[UnconditionalSuppressMessage]for IL2026/IL3050MSTestAdapter.PlatformServices/Helpers/ManagedNameHelper.csMSTestAdapter.PlatformServices/Extensions/MethodInfoExtensions.csConstructGenericMethodMSTestAdapter.PlatformServices/TestMethodFilter.cs[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072")]onGetTestCaseFilterFromDiscoveryContextWhat the attributes actually do for end users
[UnconditionalSuppressMessage("...", "ILxxxx")]does two things at different times:#pragma).dotnet publish /p:PublishTrimmed=true(orPublishAot=true) time: the suppression is baked into IL metadata, so ILC's analyzer reads it and stops reporting the corresponding warning from MSTest's assemblies into the consumer's build output.Important caveat — these attributes do not make the reflection-mode adapter trim/AOT-safe at runtime. They only stop the analyzer noise. MSTest's source-generator path remains the only AOT-safe entry point. The justifications make that explicit.
[RequiresUnreferencedCode]/[RequiresDynamicCode]onReflectionTestMethodInfo.MakeGenericMethoddo the opposite — they propagate a requirement to callers, matching the baseMethodInfo.MakeGenericMethodannotations and restoring override consistency (which itself was an analyzer error: IL2046/IL3051).New acceptance test
This PR also adds
MSTest.Acceptance.IntegrationTests.TrimTests.Publish_WithTestAdapter_DoesNotSurfaceWarningsFromSuppressedSources. It:MSTest.TestAdapter+MSTest.TestFramework+Microsoft.Testing.Platform,PublishTrimmed=true+TrimmerSingleWarn=false,<TrimmerRootAssembly>to force trim analysis of the full surface of the assemblies we changed (MSTestAdapter.PlatformServices,Microsoft.Testing.Extensions.VSTestBridge,MSTest.TestFramework),TestSourceHost.cs,DeploymentUtilityBase.cs,ReflectionOperations.cs, etc.) no longer appear in publish output.The trimmer includes source-file paths in its IL2xxx/IL3xxx messages, so absence ≡ the suppression attributes are being honored. The test does not enable
TreatWarningsAsErrorsbecause out-of-scope warnings (vstest submodule,System.Private.DataContractSerializationinternals) would otherwise fail it; the assertions on specific source-file names are scoped to MSTest's own code.Out of scope (deferred)
These warnings from the same #8586 test output are intentionally not addressed here:
MSTestSourceGeneratedReflectionMetadata.g.csIL2070 — belongs in the source generator emitter (fix in Add MSTest reflection source generator (issue #1837) #8586 or a generator-side follow-up).Microsoft.TestPlatform.ObjectModelwarnings (TestObject.cs,TestProperty.cs,CustomKeyValueConverter.cs,CustomStringArrayConverter.cs) — that's the vstest submodule, not this repo.System.Private.DataContractSerialization.[RequiresUnreferencedCode]ontoIReflectionOperations) — out of scope for a mechanical conversion.Local validation
MSTestAdapter.PlatformServices,TestFramework,Microsoft.Testing.Extensions.VSTestBridgeand the acceptance test project all build with 0 warnings / 0 errors.