[tools] go/analysis/passes/inline: fix panic in inlineAlias with instantiated generic alias

0 views
Skip to first unread message

Hyang-Ah Hana Kim (Gerrit)

unread,
9:39 AM (6 hours ago) 9:39 AM
to goph...@pubsubhelper.golang.org, Hyang-Ah Hana Kim, golang-co...@googlegroups.com

Hyang-Ah Hana Kim has uploaded the change for review

Commit message

go/analysis/passes/inline: fix panic in inlineAlias with instantiated generic alias

Moving the import collection logic to after the RHS instantiation ensures
that all necessary packages from the instantiated RHS are identified and
imported, preventing the 'package path has no import prefix' panic.

Fixes golang/go#77844
Change-Id: I45db22a62d371804b837bf0957b25625e9413487

Change diff

diff --git a/go/analysis/passes/inline/inline.go b/go/analysis/passes/inline/inline.go
index 954377d..db08593 100644
--- a/go/analysis/passes/inline/inline.go
+++ b/go/analysis/passes/inline/inline.go
@@ -321,41 +321,9 @@
// We can replace A with rhs if no name in rhs is shadowed at n's position,
// and every package in rhs is importable by the current package.

- var (
- importPrefixes = map[string]string{curPath: ""} // from pkg path to prefix
- edits []analysis.TextEdit
- )
- for _, tn := range typenames(rhs) {
- // Ignore the type parameters of the alias: they won't appear in the result.
- if typeParamNames[tn] {
- continue
- }
- var pkgPath, pkgName string
- if pkg := tn.Pkg(); pkg != nil {
- pkgPath = pkg.Path()
- pkgName = pkg.Name()
- }
- if pkgPath == "" || pkgPath == curPath {
- // The name is in the current package or the universe scope, so no import
- // is required. Check that it is not shadowed (that is, that the type
- // it refers to in rhs is the same one it refers to at n).
- scope := a.pass.TypesInfo.Scopes[curFile].Innermost(id.Pos()) // n's scope
- _, obj := scope.LookupParent(tn.Name(), id.Pos()) // what qn.name means in n's scope
- if obj != tn {
- return
- }
- } else if !packagepath.CanImport(a.pass.Pkg.Path(), pkgPath) {
- // If this package can't see the package of this part of rhs, we can't inline.
- return
- } else if _, ok := importPrefixes[pkgPath]; !ok {
- // Use AddImport to add pkgPath if it's not there already. Associate the prefix it assigns
- // with the package path for use by the TypeString qualifier below.
- prefix, eds := refactor.AddImport(
- a.pass.TypesInfo, curFile, pkgName, pkgPath, tn.Name(), id.Pos())
- importPrefixes[pkgPath] = strings.TrimSuffix(prefix, ".")
- edits = append(edits, eds...)
- }
- }
+ // We can replace A with rhs if no name in rhs is shadowed at n's position,
+ // and every package in rhs is importable by the current package.
+
// Find the complete identifier, which may take any of these forms:
// Id
// Id[T]
@@ -386,6 +354,44 @@
instAlias, _ := types.Instantiate(nil, alias, slices.Collect(targs.Types()), false)
rhs = instAlias.(*types.Alias).Rhs()
}
+
+ var (
+ importPrefixes = map[string]string{curPath: ""} // from pkg path to prefix
+ edits []analysis.TextEdit
+ )
+ for _, tn := range typenames(rhs) {
+ // Ignore the type parameters of the alias: they won't appear in the result.
+ if typeParamNames[tn] {
+ continue
+ }
+ var pkgPath, pkgName string
+ if pkg := tn.Pkg(); pkg != nil {
+ pkgPath = pkg.Path()
+ pkgName = pkg.Name()
+ }
+ if pkgPath == "" || pkgPath == curPath {
+ // The name is in the current package or the universe scope, so no import
+ // is required. Check that it is not shadowed (that is, that the type
+ // it refers to in rhs is the same one it refers to at n).
+ scope := a.pass.TypesInfo.Scopes[curFile].Innermost(id.Pos()) // n's scope
+ _, obj := scope.LookupParent(tn.Name(), id.Pos()) // what qn.name means in n's scope
+ if obj != tn {
+ return
+ }
+ } else if !packagepath.CanImport(a.pass.Pkg.Path(), pkgPath) {
+ // If this package can't see the package of this part of rhs, we can't inline.
+ return
+ } else if _, ok := importPrefixes[pkgPath]; !ok {
+ // Use AddImport to add pkgPath if it's not there already. Associate the prefix it assigns
+ // with the prefix it assigns
+ // with the package path for use by the TypeString qualifier below.
+ prefix, eds := refactor.AddImport(
+ a.pass.TypesInfo, curFile, pkgName, pkgPath, tn.Name(), id.Pos())
+ importPrefixes[pkgPath] = strings.TrimSuffix(prefix, ".")
+ edits = append(edits, eds...)
+ }
+ }
+
// To get the replacement text, render the alias RHS using the package prefixes
// we assigned above.
newText := types.TypeString(rhs, func(p *types.Package) string {
diff --git a/go/analysis/passes/inline/issue77844_test.go b/go/analysis/passes/inline/issue77844_test.go
new file mode 100644
index 0000000..91c6964
--- /dev/null
+++ b/go/analysis/passes/inline/issue77844_test.go
@@ -0,0 +1,16 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package inline
+
+import (
+ "golang.org/x/tools/go/analysis/analysistest"
+ "golang.org/x/tools/internal/testfiles"
+ "testing"
+)
+
+func TestIssue77844(t *testing.T) {
+ dir := testfiles.ExtractTxtarFileToTmp(t, "testdata/src/issue77844.txtar")
+ analysistest.Run(t, dir, Analyzer, "example.com/main")
+}
diff --git a/go/analysis/passes/inline/testdata/src/issue77844.txtar b/go/analysis/passes/inline/testdata/src/issue77844.txtar
new file mode 100644
index 0000000..6a42236
--- /dev/null
+++ b/go/analysis/passes/inline/testdata/src/issue77844.txtar
@@ -0,0 +1,27 @@
+-- go.mod --
+module example.com
+
+go 1.24
+
+-- lib/lib.go --
+package lib
+
+//go:fix inline
+type Alias[T any] = []T
+
+-- other/other.go --
+package other
+
+type Other int
+
+-- main/main.go --
+package main
+
+import (
+ "example.com/lib"
+ "example.com/other"
+)
+
+func _() {
+ var _ lib.Alias[other.Other] // want "Type alias lib.Alias.other.Other. should be inlined"
+}

Change information

Files:
  • M go/analysis/passes/inline/inline.go
  • A go/analysis/passes/inline/issue77844_test.go
  • A go/analysis/passes/inline/testdata/src/issue77844.txtar
Change size: M
Delta: 3 files changed, 84 insertions(+), 35 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: I45db22a62d371804b837bf0957b25625e9413487
Gerrit-Change-Number: 749800
Gerrit-PatchSet: 1
Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Hyang-Ah Hana Kim (Gerrit)

unread,
9:47 AM (6 hours ago) 9:47 AM
to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Hyang-Ah Hana Kim

Hyang-Ah Hana Kim uploaded new patchset

Hyang-Ah Hana Kim uploaded patch set #2 to this change.
Following approvals got outdated and were removed:
  • TryBots-Pass: LUCI-TryBot-Result-1 by Go LUCI
Open in Gerrit

Related details

Attention is currently required from:
  • Hyang-Ah Hana Kim
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newpatchset
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: I45db22a62d371804b837bf0957b25625e9413487
Gerrit-Change-Number: 749800
Gerrit-PatchSet: 2
Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Hyang-Ah Hana Kim (Gerrit)

unread,
9:50 AM (5 hours ago) 9:50 AM
to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Hyang-Ah Hana Kim

Hyang-Ah Hana Kim uploaded new patchset

Hyang-Ah Hana Kim uploaded patch set #3 to this change.
Open in Gerrit

Related details

Attention is currently required from:
  • Hyang-Ah Hana Kim
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newpatchset
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: I45db22a62d371804b837bf0957b25625e9413487
Gerrit-Change-Number: 749800
Gerrit-PatchSet: 3
unsatisfied_requirement
satisfied_requirement
open
diffy

Hyang-Ah Hana Kim (Gerrit)

unread,
9:56 AM (5 hours ago) 9:56 AM
to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Hyang-Ah Hana Kim

Hyang-Ah Hana Kim uploaded new patchset

Hyang-Ah Hana Kim uploaded patch set #4 to this change.
Open in Gerrit

Related details

Attention is currently required from:
  • Hyang-Ah Hana Kim
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newpatchset
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: I45db22a62d371804b837bf0957b25625e9413487
Gerrit-Change-Number: 749800
Gerrit-PatchSet: 4
unsatisfied_requirement
satisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages