Skip to content

fix(analyzers): remove incorrect AOT rules TUnit0300/0301/0302 (#5722)#5746

Merged
thomhurst merged 1 commit intomainfrom
fix/5722-aot-analyzer-rules
Apr 26, 2026
Merged

fix(analyzers): remove incorrect AOT rules TUnit0300/0301/0302 (#5722)#5746
thomhurst merged 1 commit intomainfrom
fix/5722-aot-analyzer-rules

Conversation

@thomhurst
Copy link
Copy Markdown
Owner

Closes #5722

Summary

  • Removes TUnit0300, TUnit0301, TUnit0302 — issue documents all three are inaccurate (LLM-hallucinated) and fire even when AOT is not enabled.
  • Updates AnalyzerReleases.Unshipped.md with Removed Rules entries per Roslyn release-tracking conventions.
  • Deletes AotCompatibilityAnalyzer and its tests; removes corresponding strings from Resources.resx and descriptors from Rules.cs.

Test plan

  • Analyzer project builds clean
  • Removed tests gone; remaining analyzer tests unaffected

…301/0302 (#5722)

These rules produced false positives even outside AOT contexts and the
underlying claims (generics in InheritsTests, ValueTuple, conversion ops)
do not actually break AOT.
Copy link
Copy Markdown
Contributor

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is a clean, well-executed removal of three inaccurate Roslyn analyzer rules (, , ). The PR is straightforward and the rationale is solid.

What's Done Well

Roslyn release-tracking conventions are correctly followed. Adding "Removed Rules" entries to AnalyzerReleases.Unshipped.md is required for NuGet analyzer packages so that tooling can warn consumers about suppressed rule IDs that no longer exist. This is the right approach.

Complete cleanup. All four artifact types are removed together: the analyzer class, its tests, the DiagnosticDescriptor fields in Rules.cs, and the Resources.resx strings. No dangling references remain.

The dead code identified in the issue is correctly characterized.

  • TUnit0301 was guarded by #if !NET, making it a no-op on every modern .NET target — a firing analyzer that literally never fired.
  • TUnit0302 had resource strings but no DiagnosticDescriptor and no detection logic — a ghost rule.
  • HasAotCompatibleAttribute referenced an attribute (AotCompatibleAttribute) that TUnit never defined, so it would always return false.

Minor Observations (Non-blocking)

1. Check AnalyzerReleases.Shipped.md for prior entries.
If these rules were ever included in a prior NuGet release, they should appear in Shipped.md with a status of Removed or similar, not just Unshipped.md. If they were only ever in pre-release builds that never shipped, the current approach is fine. Worth a quick sanity-check to confirm the release history is consistent.

2. Consumers with #pragma warning disable TUnit0300/0301/0302 will get a new warning.
Once this ships, anyone who added a suppression to silence these false positives will see CS8032/similar "unrecognized diagnostic ID" warnings. This is unavoidable and is the correct behavior (suppressed dead rules should be cleaned up), but a brief release note or mention in the PR description would help users know what to do. Not a blocker.

Verdict

No issues with the implementation. This is a pure subtraction with no behavioral regressions — the rules were either never firing or firing incorrectly. Removing them is the right call. The 4 additions / 292 deletions ratio speaks for itself.

Copy link
Copy Markdown
Contributor

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is a clean, well-executed removal of three inaccurate Roslyn analyzer rules (TUnit0300, TUnit0301, TUnit0302). The PR is straightforward and the rationale is solid.

What's Done Well

Roslyn release-tracking conventions are correctly followed. Adding "Removed Rules" entries to AnalyzerReleases.Unshipped.md is required for NuGet analyzer packages so that tooling can warn consumers about suppressed rule IDs that no longer exist. This is the right approach.

Complete cleanup. All four artifact types are removed together: the analyzer class, its tests, the DiagnosticDescriptor fields in Rules.cs, and the Resources.resx strings. No dangling references remain.

The dead code identified in the issue is correctly characterized.

  • TUnit0301 was guarded by #if !NET, making it a no-op on every modern .NET target — an analyzer that literally never fired.
  • TUnit0302 had resource strings but no DiagnosticDescriptor and no detection logic — a ghost rule.
  • HasAotCompatibleAttribute referenced an attribute (AotCompatibleAttribute) that TUnit never defined, so it would always return false.

Minor Observations (Non-blocking)

1. Check AnalyzerReleases.Shipped.md for prior entries.
If these rules were included in a prior NuGet release, they should also appear in Shipped.md marked as Removed. If they were only ever in pre-release builds that never shipped, the current approach is fine. Worth a quick sanity-check to confirm the release history is consistent.

2. Consumers with #pragma warning disable TUnit0300/0301/0302 will get a new warning.
Once this ships, anyone who added a suppression to silence these false positives will see "unrecognized diagnostic ID" warnings. This is correct behavior (dead suppressions should be cleaned up), but a brief release note or mention in the changelog would help users know what to do. Not a blocker.

Verdict

No issues with the implementation. This is a pure subtraction with no behavioral regressions — the rules were either never firing or firing incorrectly. Removing them is the right call. The 4 additions / 292 deletions ratio speaks for itself.

@codacy-production
Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@thomhurst thomhurst merged commit f931174 into main Apr 26, 2026
15 of 16 checks passed
@thomhurst thomhurst deleted the fix/5722-aot-analyzer-rules branch April 26, 2026 08:47
This was referenced Apr 26, 2026
intellitect-bot pushed a commit to IntelliTect/EssentialCSharp.Web that referenced this pull request Apr 27, 2026
Updated [TUnit](https://github.com/thomhurst/TUnit) from 1.39.0 to
1.40.5.

<details>
<summary>Release notes</summary>

_Sourced from [TUnit's
releases](https://github.com/thomhurst/TUnit/releases)._

## 1.40.5

<!-- Release notes generated using configuration in .github/release.yml
at v1.40.5 -->

## What's Changed
### Other Changes
* Fix reflection property injection reuse by @​thomhurst in
thomhurst/TUnit#5763
* fix(assertions): gate IsEqualTo<TValue, TOther> overload to net9+
(#​5765) by @​thomhurst in thomhurst/TUnit#5767
### Dependencies
* chore(deps): update tunit to 1.40.0 by @​thomhurst in
thomhurst/TUnit#5762


**Full Changelog**:
thomhurst/TUnit@v1.40.0...v1.40.5

## 1.40.0

<!-- Release notes generated using configuration in .github/release.yml
at v1.40.0 -->

## What's Changed
### Other Changes
* perf(engine): collapse async forwarding wrappers in test execution
(#​5714) by @​thomhurst in thomhurst/TUnit#5725
* perf(engine): skip Console.Out/Err FlushAsync when no output captured
(#​5712) by @​thomhurst in thomhurst/TUnit#5724
* perf(engine): collapse async state machines on hook cache-hit /
empty-hook path (#​5713) by @​thomhurst in
thomhurst/TUnit#5726
* perf: eliminate per-test closure + GetOrAdd factory alloc (#​5710) by
@​thomhurst in thomhurst/TUnit#5727
* perf(engine): replace global lock in EventReceiverRegistry with
lock-free CAS by @​thomhurst in
thomhurst/TUnit#5731
* perf(engine): batch per-test overhead cleanups (#​5719) by @​thomhurst
in thomhurst/TUnit#5730
* #​5733 handling all arguments for Fact and Theory by @​inyutin-maxim
in thomhurst/TUnit#5734
* fix(assertions): prefer string overload of Member() over
IEnumerable<char> (#​5702) by @​thomhurst in
thomhurst/TUnit#5721
* fix(migration): preserve comments/XML docs when removing sole
attributes (#​5698) by @​thomhurst in
thomhurst/TUnit#5739
* perf(build): trim test TFMs and skip viewer dump by default by
@​thomhurst in thomhurst/TUnit#5741
* fix(pipeline): skip TestBaseModule frameworks with missing binaries by
@​thomhurst in thomhurst/TUnit#5752
* feat(assertions): focused diff messages for IsEqualTo/IsEquivalentTo
(#​5732) by @​thomhurst in thomhurst/TUnit#5747
* fix(analyzers): remove incorrect AOT rules TUnit0300/0301/0302
(#​5722) by @​thomhurst in thomhurst/TUnit#5746
* perf(engine): lazy hook metadata registration (#​5448) by @​thomhurst
in thomhurst/TUnit#5750
* chore(templates): unify TUnit version pinning to 1.* (#​5709) by
@​thomhurst in thomhurst/TUnit#5743
* fix(templates): floating TUnit.Aspire version (#​5708) by @​thomhurst
in thomhurst/TUnit#5742
* fix(assertions): preserve specialised source in .Count(itemAssertion)
(#​5707) by @​thomhurst in thomhurst/TUnit#5749
* feat(assertions): IsEqualTo with implicitly-convertible wrappers
(#​5720) by @​thomhurst in thomhurst/TUnit#5751
* feat(aspire): add ability to manually remove resources by @​Odonno in
thomhurst/TUnit#5586
* fix(fscheck): register default CancellationToken arbitrary that
surfaces TestContext token by @​JohnVerheij in
thomhurst/TUnit#5758
* fix(engine): allow keyed NotInParallel tests to run alongside
unconstrained tests (#​5700) by @​thomhurst in
thomhurst/TUnit#5740
* perf: skip TimeoutHelper wrap when no explicit [Timeout] is set
(#​5711) by @​thomhurst in thomhurst/TUnit#5728
### Dependencies
* chore(deps): update tunit to 1.39.0 by @​thomhurst in
thomhurst/TUnit#5701
* chore(deps): update aspire to 13.2.4 by @​thomhurst in
thomhurst/TUnit#5735
* chore(deps): bump postcss from 8.5.6 to 8.5.10 in /docs by
@​dependabot[bot] in thomhurst/TUnit#5736
* chore(deps): update dependency fscheck to 3.3.3 by @​thomhurst in
thomhurst/TUnit#5760

## New Contributors
* @​inyutin-maxim made their first contribution in
thomhurst/TUnit#5734
* @​Odonno made their first contribution in
thomhurst/TUnit#5586

**Full Changelog**:
thomhurst/TUnit@v1.39.0...v1.40.0

Commits viewable in [compare
view](thomhurst/TUnit@v1.39.0...v1.40.5).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=TUnit&package-manager=nuget&previous-version=1.39.0&new-version=1.40.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: AOT Compatibility Rules (TUnit0300,TUnit0301,TUnit0302) are incorrect

1 participant