Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer#9941
Merged
Evangelink merged 6 commits intoJul 15, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Suppresses the IL2026 trim/AOT warning from assembly fixture provider discovery while extending acceptance-test coverage.
Changes:
- Isolates and suppresses
Assembly.GetReferencedAssemblies(). - Adds the source file to trim/AOT warning assertions.
Show a summary per file
| File | Description |
|---|---|
TypeCache.ProviderDiscovery.cs |
Adds the scoped IL2026 suppression helper. |
TrimAndAotAssertions.cs |
Guards against future trim/AOT warnings from provider discovery. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Medium
This comment has been minimized.
This comment has been minimized.
AssemblyFixtureProvider cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies + load-by-name), which requires capabilities not available when the runtime cannot generate dynamic code (Native AOT, Mono iOS AOT, Blazor WASM AOT). Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported so the feature is skipped there. Because the ILC substitutes IsDynamicCodeSupported with a constant under AOT, the guarded reflection path is statically removed, so the previously-surfaced IL2026 (from Assembly.GetReferencedAssemblies) disappears without needing an inline suppression. This supersedes the earlier suppression approach.
…ative AOT Since [AssemblyFixtureProvider] discovery is now skipped under Native AOT (it relies on walking the runtime assembly reference graph), add an analyzer that warns at build time when a project both opts into PublishAot and declares [assembly: AssemblyFixtureProvider], so the silently-ignored feature is surfaced to the user. PublishAot is exposed to analyzers via a new CompilerVisibleProperty in MSTest.TestAdapter.targets. The diagnostic reports at each attribute application; includes resources (+ regenerated xlf), release tracking, and unit tests.
Evangelink
force-pushed
the
dev/amauryleve/aot-il2026-assembly-fixture-provider
branch
from
July 14, 2026 15:37
359ff8b to
b54f046
Compare
This comment has been minimized.
This comment has been minimized.
Evangelink
enabled auto-merge (squash)
July 15, 2026 07:29
…ime warning - MSTEST0072 now also inspects referenced assemblies' attributes, so the documented default usage (attribute on a referenced fixture library) is flagged with a no-location diagnostic on the consuming Native AOT project, not just self-applied attributes. - Add a runtime warning when discovery is skipped because dynamic code is unsupported, covering Mono iOS AOT and Blazor WebAssembly AOT which the PublishAot-keyed analyzer cannot reach. The check is metadata-only (HasAssemblyFixtureProviderMarker) so it stays AOT-safe. - Use explicit LINQ filtering (.Where/.Any) in the analyzer loops per code-quality feedback. - Add unit tests for the referenced-assembly scenario (PublishAot true and false).
0101
approved these changes
Jul 15, 2026
This comment has been minimized.
This comment has been minimized.
…tance test, encoding, LINQ - Runtime warning now scans already-loaded assemblies (AppDomain.GetAssemblies, metadata-only) instead of only the test assembly, so a referenced provider library is no longer silent on Mono iOS / Blazor WASM AOT. Stays AOT-safe (no reference-graph walk). - Add acceptance test AssemblyFixtureProviderNativeAotTests verifying that under PublishAot=true (IsDynamicCodeSupported=false, managed) the provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes. - Restore UTF-8 BOM on all touched .cs files per .editorconfig. - Use explicit .Where(...) in the referenced-assembly loop.
This comment has been minimized.
This comment has been minimized.
0101
approved these changes
Jul 15, 2026
- Isolate per-assembly failures in the runtime warning loop (try/catch around the metadata probe) so unresolvable custom-attribute metadata on one loaded assembly cannot abort discovery, matching the normal discovery path. Clarify in comments that the runtime probe is best-effort (already-loaded assemblies only) and that referenced-provider coverage is the analyzer's responsibility. - Broaden MSTEST0072 to also trigger on RunAOTCompilation (Blazor WebAssembly AOT) in addition to PublishAot, giving build-time detection for another dynamic-code-disabled runtime. Added RunAOTCompilation as a CompilerVisibleProperty and a unit test. - Replace the referenced-assembly foreach (whose loop variable was unused) with a single .Any(...) check that reports one no-location diagnostic, fixing the useless-assignment warning.
0101
approved these changes
Jul 15, 2026
This comment has been minimized.
This comment has been minimized.
MSTEST0072 now triggers on RunAOTCompilation (Blazor WebAssembly AOT) as well as PublishAot, so the diagnostic title/message/description no longer say only 'Native AOT'. Reword to 'ahead-of-time compilation (such as Native AOT or Blazor WebAssembly AOT)' and regenerate the XLF files for all locales.
0101
approved these changes
Jul 15, 2026
Contributor
🧪 Test quality grade — PR #9941
This advisory comment was generated automatically. Grades are heuristic Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "awmgmcpg"See Network Configuration for more information.
|
Evangelink
disabled auto-merge
July 15, 2026 10:47
Evangelink
enabled auto-merge (squash)
July 15, 2026 10:47
Evangelink
deleted the
dev/amauryleve/aot-il2026-assembly-fixture-provider
branch
July 15, 2026 10:47
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.
Summary
[AssemblyFixtureProvider]cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies()+ load-by-name viaAssemblyLoadContext). That is fundamentally a reflection/runtime-loading mechanism and cannot be made reflection-free by the source generator. Under Native AOT it also surfaced anIL2026— the last MSTest-owned trim/AOT warning a consumer hit when publishing a Native AOT test app withMSTestSourceGenMode=ReflectionFreeand warnings-as-errors.Rather than paper over it with a suppression, this PR makes the behavior explicit: skip the feature when dynamic code is unsupported, and surface it both at build time (analyzer) and at run time (trace warning).
Changes
1. Skip discovery when dynamic code is unsupported (
TypeCache.ProviderDiscovery.cs)Guard
DiscoverFixturesFromProvidersonRuntimeFeature.IsDynamicCodeSupported. Because ILC constant-folds that switch tofalseunder AOT, the guarded reflection path is statically removed — so theIL2026disappears with no suppression needed (same pattern already used inDataSerializationHelper).2. Best-effort runtime warning
When discovery is skipped, emit a trace warning so consumers are not silently deprived of their fixtures. It scans the already-loaded assemblies (
AppDomain.GetAssemblies, metadata-only viaCustomAttributeData, with per-assembly failure isolation) — it deliberately does not walk the reference graph, so it stays AOT-safe. Consequently it can only see markers on assemblies that happen to be loaded (e.g. a self-applied marker on the test assembly); an unloaded referenced provider is not detectable at run time AOT-safely. Referenced providers are instead covered at build time by the analyzer. The warning is emitted through MTP's diagnostic logger (--diagnosticoutput).3. New analyzer MSTEST0072 —
AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerWarns at build time when the project opts into an AOT flavor detectable at build time —
PublishAot(Native AOT) orRunAOTCompilation(Blazor WebAssembly AOT) — and[AssemblyFixtureProvider]is in play. It inspects both the compilation's own assembly attributes (reported at the attribute location) and referenced assemblies' attributes (reported as a no-location diagnostic), so the documented default usage — the attribute placed on a referenced fixture library consumed by an AOT test project — is covered.PublishAotandRunAOTCompilationare exposed to analyzers via newCompilerVisiblePropertyentries inMSTest.TestAdapter.targets. Includes resources (+ regenerated xlf for all 13 locales),AnalyzerReleases.Unshipped.mdentry, and unit tests (including the referenced-assembly andRunAOTCompilationscenarios).4. Acceptance test —
AssemblyFixtureProviderNativeAotTestsverifies that underPublishAot=true(which setsIsDynamicCodeSupported=falsefor a managed build) the referenced provider'sAssemblyInitialize/AssemblyCleanupare skipped while the test still passes.Notes
[AssemblyFixtureProvider]whether it is declared in the compilation being built or on a referenced library, and it triggers on both build-time-detectable AOT flavors (PublishAot,RunAOTCompilation). The only case it cannot cover is a runtime that disables dynamic code without either build property being set (e.g. Mono iOS AOT), where there is no build-time signal to key off; the best-effort runtime trace warning is the fallback there, limited to already-loaded assemblies as described in change Porting latest changes. #2.Validation
dotnet buildof the adapter (net8.0) andMSTest.Analyzers→ 0 errors (release-tracking analyzer satisfied).RunAOTCompilationcases) pass on net8.0.