Skip to content

Fix MA0075 false positive on FormattableString.Invariant - #1322

Merged
meziantou merged 1 commit into
mainfrom
feature/meziantou-analyzer-1321-a2ba39
Aug 26, 2026
Merged

Fix MA0075 false positive on FormattableString.Invariant#1322
meziantou merged 1 commit into
mainfrom
feature/meziantou-analyzer-1321-a2ba39

Conversation

@meziantou

Copy link
Copy Markdown
Owner

Fixes #1321

Problem

Since 3.0.150 (#1273), MA0075 reports FormattableString.Invariant($"...") when the result is used directly as an operand of a string concatenation:

_ = System.FormattableString.Invariant($"abc{1:N0}") + b; // MA0075

Storing the result in a local first was already accepted, so the inline form should be too.

Cause

CultureSensitiveFormattingContext.GetCultureSensitivity calls GetInterpolatedStringArgumentCultureSensitivity for invocations, which treats any invocation with a FormattableString (or interpolated string handler) argument as producing the culture sensitivity of that argument, and returns before anything else is considered. For Invariant($"abc{1:N0}") the argument is culture sensitive, so the whole invocation was classified as culture sensitive — even though Invariant exists precisely to format that argument with CultureInfo.InvariantCulture.

Fix

Add System.FormattableString.Invariant(System.FormattableString) to CreateExcludedMethods, which is consulted before the interpolated string argument path.

I used the excluded-methods list rather than skipping every method whose containing type is System.FormattableString, because FormattableString.CurrentCulture lives on the same type and is genuinely culture sensitive — it must keep being reported. FormattableString.ToString(IFormatProvider) and string.Create(IFormatProvider, ...), also mentioned in the issue, were already covered by the existing HasArgumentOfType(FormatProviderSymbol) check, so they needed no change.

Tests

  • FormattableString_Invariant_StringConcat covers the four concatenation forms from the issue (left operand, right operand, both operands, parenthesized).
  • FormattableString_CurrentCulture_StringConcat locks in that FormattableString.CurrentCulture is still reported.

Verification

  • Confirmed the new test fails on the unpatched analyzer and passes with the fix.
  • Full test suite passes on roslyn5.9 (3774 tests) and roslyn4.8 (3643 tests).
  • dotnet run --project src/DocumentationGenerator exits 0 with no markdown changes.

GetCultureSensitivity classifies any invocation that takes a
FormattableString argument with the culture sensitivity of that
argument, before checking anything else. FormattableString.Invariant
formats its argument with CultureInfo.InvariantCulture, so the result is
culture insensitive, but the invocation was reported as culture
sensitive when used as an operand of a string concatenation.

Add FormattableString.Invariant to the excluded methods, which are
checked before the interpolated string argument. FormattableString.CurrentCulture
is on the same type but is genuinely culture sensitive, so it keeps
being reported.

Fixes #1321
@meziantou
meziantou enabled auto-merge (squash) August 26, 2026 14:33
@meziantou
meziantou merged commit e2b2a59 into main Aug 26, 2026
12 checks passed
@meziantou
meziantou deleted the feature/meziantou-analyzer-1321-a2ba39 branch August 26, 2026 14:39
This was referenced Aug 26, 2026
IhateTrains pushed a commit to ParadoxGameConverters/ImperatorToCK3 that referenced this pull request Aug 27, 2026
Updated
[Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer)
from 3.0.177 to 3.0.184.

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

_Sourced from [Meziantou.Analyzer's
releases](https://github.com/meziantou/Meziantou.Analyzer/releases)._

## 3.0.184

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.184>

## What's Changed
* Compute the package version from the git tags instead of nuget.org by
@​meziantou in meziantou/Meziantou.Analyzer#1350


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.183...3.0.184

## 3.0.183

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.183>

## What's Changed
* Fix MA0026 crash on an unterminated block comment (#​1328) by
@​meziantou in meziantou/Meziantou.Analyzer#1346
* Fix MA0050 code fixer producing an extension local function (CS1106)
by @​meziantou in
meziantou/Meziantou.Analyzer#1348
* Fix MA0028 code fixer producing uncompilable code (#​1327) by
@​meziantou in meziantou/Meziantou.Analyzer#1347
* Fail the tests when an analyzer throws by @​meziantou in
meziantou/Meziantou.Analyzer#1349


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.182...3.0.183

## 3.0.182

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.182>

## What's Changed
* Fix MA0073 code fixer producing uncompilable code for low-precedence
operands by @​meziantou in
meziantou/Meziantou.Analyzer#1344
* Do not crash on an invalid regex in the .editorconfig (MA0003, MA0104)
by @​meziantou in
meziantou/Meziantou.Analyzer#1345


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.181...3.0.182

## 3.0.181

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.181>

## What's Changed
* Add a language attribute code fix and MA0218/MA0219 for XML comments
by @​meziantou in
meziantou/Meziantou.Analyzer#1320
* Compile the text produced by the fixer in the test harness by
@​meziantou in meziantou/Meziantou.Analyzer#1342
* Fix StackOverflow crash on cyclic local initializers
(MA0091/MA0092/MA0093) by @​meziantou in
meziantou/Meziantou.Analyzer#1341
* Avoid the Sqlite data-flow analysis on every MA0042 invocation by
@​meziantou in meziantou/Meziantou.Analyzer#1343


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.180...3.0.181

## 3.0.180

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.180>

## What's Changed
* Fix MAS0004 stopping at the first unrelated CA1507 diagnostic by
@​meziantou in meziantou/Meziantou.Analyzer#1340


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.179...3.0.180

## 3.0.179

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.179>

## What's Changed
* Fix bare `#pragma warning disable` in AvoidUsingRedundantElseAnalyzer
by @​meziantou in
meziantou/Meziantou.Analyzer#1339


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.178...3.0.179

## 3.0.178

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.178>

## What's Changed
* Fix MA0075 false positive on FormattableString.Invariant by
@​meziantou in meziantou/Meziantou.Analyzer#1322


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.177...3.0.178

Commits viewable in [compare
view](meziantou/Meziantou.Analyzer@3.0.177...3.0.184).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Meziantou.Analyzer&package-manager=nuget&previous-version=3.0.177&new-version=3.0.184)](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>
This was referenced Aug 27, 2026
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.

MA0075 false positive: FormattableString.Invariant($"...") used as operand of string +

1 participant