Skip to content

fix(generator): qualify method receivers that collide with arm/storage import aliases#5504

Merged
theunrepentantgeek merged 2 commits into
Azure:mainfrom
andreidorin-oprea:fix/generator-storage-receiver-alias
Jul 2, 2026
Merged

fix(generator): qualify method receivers that collide with arm/storage import aliases#5504
theunrepentantgeek merged 2 commits into
Azure:mainfrom
andreidorin-oprea:fix/generator-storage-receiver-alias

Conversation

@andreidorin-oprea

Copy link
Copy Markdown
Contributor

Problem

CreateReceiver() derives a method-receiver name from the last word of a type name. For a type whose
name ends in Storage (e.g. FunctionsDeployment_Storage in the web group), the receiver becomes
storage — which shadows the storage conversion-package import alias used in generated
AssignProperties_To_* / AssignProperties_From_* methods. The generated code then fails to compile,
e.g. storage.FunctionsDeployment_Storage_Authentication is not a type.

CreateReceiver already qualifies Go reserved words and very short (≤3-char) identifiers — so arm
(len 3) was already safe, but storage was not. This extends the same guard to the fixed
conversion-package import aliases (arm, storage) so a type-derived receiver can never shadow them.
The receiver is renamed (e.g. storagedeploymentStorage); type names and JSON wire tags are
unchanged.

General fix: any current or future type whose name ends in Storage (or otherwise collides with these
aliases) benefits.

Tests

  • go test ./internal/astmodel/... (incl. a new case covering the receiver/alias collision) → ok
  • go test ./internal/codegen/... (golden tests) → ok, no regressions

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the ASO v2 code generator’s receiver-naming logic to prevent generated method receivers from shadowing conversion-package imports (notably arm and storage), which can otherwise cause compile failures in generated assignment/conversion code.

Changes:

  • Extend CreateReceiver() to qualify receiver names when the type-derived base name collides with known conversion-package names (arm, storage) in addition to the existing reserved-word and short-identifier guards.
  • Introduce a shared forbiddenReceiverNames set to centralize these disallowed receiver names.
  • Add a unit test case covering the *Storage collision scenario (including the Status-suffixed variant).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
v2/tools/generator/internal/astmodel/identifier_factory.go Adds a forbidden receiver-name set (arm/storage) and incorporates it into receiver qualification logic.
v2/tools/generator/internal/astmodel/identifier_factory_test.go Adds regression tests ensuring *Storage types get a qualified receiver (e.g., deploymentStorage).

@andreidorin-oprea

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

@theunrepentantgeek

Copy link
Copy Markdown
Member

Thanks for the contribution, much appreciated.

The generated code then fails to compile, e.g. storage.FunctionsDeployment_Storage_Authentication is not a type.

When did this error occur? I'd like to reproduce the problem in order to verify your fix works without breaking any of the existing edge cases - getting IdentifierFactory to work originally took a lot of iteration, so I'm sure you'll understand my caution.

@theunrepentantgeek

Copy link
Copy Markdown
Member

Our build checks have failed - some of the existing code is getting a new receiver name.

This looks to be behaving as intended, and we most likely should merge this.

What I need to understand is why you are seeing compilation errors in your situation, but we haven't seen similar errors previously, even when the receiver name selected has been storage.

claude and others added 2 commits July 1, 2026 11:22
…e import aliases

A type whose name's last word is 'Storage' (e.g. FunctionsDeployment_Storage)
yielded a method receiver 'storage', shadowing the storage conversion-package
import alias in generated AssignProperties_To_* methods and breaking the build.
CreateReceiver already qualifies reserved words and short (<=3 char) names; also
qualify names that collide with the fixed conversion-package aliases (arm/storage).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The generator fix qualifies method receivers that collide with the arm/storage
conversion-package import aliases. UserOwnedStorage's last word is "Storage", so
its receiver changes from "storage" to "ownedStorage". Regenerated repo-wide;
this is the only existing type affected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@andreidorin-oprea andreidorin-oprea force-pushed the fix/generator-storage-receiver-alias branch from bbecbbe to a7e76c3 Compare July 1, 2026 08:39
@andreidorin-oprea

Copy link
Copy Markdown
Contributor Author

Sure — I hit this adding the web 2025-05-01 version (#5503). The generated conversion for the new FunctionsDeployment_Storage type wouldn't build:

storage.FunctionsDeployment_Storage_Authentication is not a type

It's down to where the receiver shadows the storage import — it only shadows it inside the method body, not in the signature. That's why the existing *Storage types have always been fine: their bodies only use storage. as field access on the receiver (e.g. storage.ResourceReference on UserOwnedStorage), never as a package qualifier.

FunctionsDeployment_Storage is the first one that trips it, because it has a nested Authentication sub-object and the conversion builds it in the body. With the receiver name the old logic picks (storage):

func (storage *FunctionsDeployment_Storage) AssignProperties_To_FunctionsDeployment_Storage(destination *storage.FunctionsDeployment_Storage) error {
    // ...
    if storage.Authentication != nil {
        var authentication storage.FunctionsDeployment_Storage_Authentication  // 'storage' is the receiver here, not the package
        err := storage.Authentication.AssignProperties_To_FunctionsDeployment_Storage_Authentication(&authentication)
        // ...
    }
}

In the body storage resolves to the receiver, so storage.FunctionsDeployment_Storage_Authentication reads as a selector on it → "is not a type". I threw together a small 4-case repro to be sure: a storage receiver builds fine when storage. is only in the signature or is field access, and fails only when the body names a type from the storage package.

So the fix just stops CreateReceiver handing out storage/arm as receiver names — same idea as the existing reserved-word/short-name guard. The only pre-existing fallout across the repo is the UserOwnedStorage receiver rename, which I've regenerated and pushed so verify-no-changes is clean.

@theunrepentantgeek

Copy link
Copy Markdown
Member

So the fix just stops CreateReceiver handing out storage/arm as receiver names — same idea as the existing reserved-word/short-name guard. The only pre-existing fallout across the repo is the UserOwnedStorage receiver rename, which I've regenerated and pushed so verify-no-changes is clean.

I understand now, thanks for the explanation. The change looks solid to me, I've set the PR checks going.

@theunrepentantgeek theunrepentantgeek added this pull request to the merge queue Jul 2, 2026
@theunrepentantgeek

Copy link
Copy Markdown
Member

Checks passed, I've queued this to merge. Thanks once again!

@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 2, 2026
@theunrepentantgeek theunrepentantgeek added this pull request to the merge queue Jul 2, 2026
Merged via the queue into Azure:main with commit a46d57b Jul 2, 2026
8 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Recently Completed in Azure Service Operator Roadmap Jul 2, 2026
@matthchr matthchr moved this from Recently Completed to Ready for Release in Azure Service Operator Roadmap Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready for Release

Development

Successfully merging this pull request may close these issues.

5 participants