Skip to content

NoLeadingUnderscores: allow leading-underscore backing properties#1217

Open
luancamara wants to merge 1 commit into
swiftlang:mainfrom
luancamara:noleadingunderscores-backing-property
Open

NoLeadingUnderscores: allow leading-underscore backing properties#1217
luancamara wants to merge 1 commit into
swiftlang:mainfrom
luancamara:noleadingunderscores-backing-property

Conversation

@luancamara

Copy link
Copy Markdown

Resolves #1150.

What

The opt-in NoLeadingUnderscores rule flags a backing property like _count even when a non-underscored sibling property count exists in the same type:

struct Counter {
  private var _count: Int = 0
  var count: Int { _count }   // `_count` was flagged
}

Using a leading underscore to name a backing store for a same-named property is a common, intentional pattern, so this exempts it from the rule. This matches the carve-out @allevato agreed to in the issue discussion, and is unconditional (no new configuration option).

How

visit(_:IdentifierPatternSyntax) now skips the diagnostic when the name starts with _ and a property whose name is the same without the leading underscore is declared directly in the same MemberBlock. The check walks up from the pattern to its enclosing type member block and scans sibling property declarations — it's stateless and localized.

Scoping decisions (each covered by a test):

  • Only properties that are direct members of a type/extension qualify; local variables and top-level bindings still flag.
  • The counterpart must be a property — a method named count does not exempt _count.
  • Matching is limited to the same member block, so a counterpart declared in a separate extension is not matched (kept out of scope for simplicity; happy to extend if desired).

Testing

  • Added cases to NoLeadingUnderscoresTests: backing property allowed, non-property counterpart still flags, scoped to the same type, and locals not exempt. All existing cases still pass.
  • swift test passes.
  • Ran swift run generate-swift-format to update Documentation/RuleDocumentation.md for the rule's new documentation comment. No visit methods were added or removed, so the generated pipeline/registry/name-cache are unchanged.

The opt-in NoLeadingUnderscores rule flagged a backing property such as `_count` even when a sibling property `count` exists in the same type, which is a common and intentional pattern for naming a backing store.

The rule now exempts a leading-underscore property name when a property whose name is the same without the leading underscore is declared in the same member block. Local variables, top-level bindings, and counterparts that are not properties (e.g. methods) are unaffected, and matching is limited to the same type body (extensions are not matched).

The carve-out is unconditional (no new configuration option), matching the approach agreed on in the issue discussion. Fixes swiftlang#1150.
@luancamara luancamara force-pushed the noleadingunderscores-backing-property branch from b354114 to 556ab1a Compare June 15, 2026 12:53
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.

Add a NoLeadingUnderscores mode that allows them when duplicating an existing property.

1 participant