[tools] imports: prefer math/rand/v2 over math/rand

107 views
Skip to first unread message

Peter Weinberger (Gerrit)

unread,
Mar 20, 2024, 12:36:13 PM3/20/24
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Peter Weinberger has uploaded the change for review

Commit message

imports: prefer math/rand/v2 over math/rand

When a program refers to 'rand.Rand()' without an import statement,
import math/rand/v2 is the proper answer. (Well, it's the better answer.
The right answer depends on the version of go the user asks for.)
Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8

Change diff

diff --git a/gopls/internal/test/integration/misc/imports_test.go b/gopls/internal/test/integration/misc/imports_test.go
index d8f453e..d46b326 100644
--- a/gopls/internal/test/integration/misc/imports_test.go
+++ b/gopls/internal/test/integration/misc/imports_test.go
@@ -81,6 +81,33 @@
})
}

+func TestIssue66407(t *testing.T) {
+ const files = `
+-- go.mod --
+module foo
+go 1.21
+-- a.go --
+package foo
+
+func f(x float64) float64 {
+ return x + rand.Rand()
+}
+`
+ WithOptions(Modes(Default)).
+ Run(t, files, func(t *testing.T, env *Env) {
+ env.OpenFile("a.go")
+ was := env.BufferText("a.go")
+ env.OrganizeImports("a.go")
+ env.SaveBuffer("a.go")
+ is := env.BufferText("a.go")
+ env.Await(Diagnostics(ForFile("a.go")))
+ diff := compare.Text(was, is)
+ if !strings.Contains(diff, "rand/v2") {
+ t.Errorf("expected rand/v2, got %q", diff)
+ }
+ })
+}
+
func TestVim1(t *testing.T) {
const vim1 = `package main

diff --git a/internal/imports/fix.go b/internal/imports/fix.go
index 69e2ad5..44c14db 100644
--- a/internal/imports/fix.go
+++ b/internal/imports/fix.go
@@ -301,6 +301,17 @@
return nil
}

+// if there is a trailing major version, remove it
+func withoutVersion(nm string) string {
+ if v := path.Base(nm); v[0] == 'v' {
+ if _, err := strconv.Atoi(v[1:]); err == nil {
+ xnm := nm[:len(nm)-len(v)-1]
+ return xnm
+ }
+ }
+ return nm
+}
+
// importIdentifier returns the identifier that imp will introduce. It will
// guess if the package name has not been loaded, e.g. because the source
// is not available.
@@ -310,7 +321,7 @@
}
known := p.knownPackages[imp.ImportPath]
if known != nil && known.name != "" {
- return known.name
+ return withoutVersion(known.name)
}
return ImportPathToAssumedName(imp.ImportPath)
}
@@ -1057,6 +1068,17 @@
if err != nil {
return err
}
+ localbase := func(nm string) string {
+ ans := path.Base(nm)
+ if ans[0] == 'v' {
+ if _, err := strconv.Atoi(ans[1:]); err == nil {
+ ix := strings.LastIndex(nm, ans)
+ more := path.Base(nm[:ix])
+ ans = path.Join(more, ans)
+ }
+ }
+ return ans
+ }
add := func(pkg string) {
// Prevent self-imports.
if path.Base(pkg) == pass.f.Name.Name && filepath.Join(goenv["GOROOT"], "src", pkg) == pass.srcDir {
@@ -1065,13 +1087,13 @@
exports := symbolNameSet(stdlib.PackageSymbols[pkg])
pass.addCandidate(
&ImportInfo{ImportPath: pkg},
- &packageInfo{name: path.Base(pkg), exports: exports})
+ &packageInfo{name: localbase(pkg), exports: exports}) // PJW: Base is not right (math/v2)
}
for left := range refs {
if left == "rand" {
- // Make sure we try crypto/rand before math/rand.
+ // Make sure we try crypto/rand before math/rand as both have Int()
add("crypto/rand")
- add("math/rand")
+ add("math/rand/v2")
continue
}
for importPath := range stdlib.PackageSymbols {

Change information

Files:
  • M gopls/internal/test/integration/misc/imports_test.go
  • M internal/imports/fix.go
Change size: M
Delta: 2 files changed, 53 insertions(+), 4 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: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
Gerrit-Change-Number: 573075
Gerrit-PatchSet: 1
Gerrit-Owner: Peter Weinberger <p...@google.com>
Gerrit-Reviewer: Peter Weinberger <p...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Kevin Burke (Gerrit)

unread,
Mar 20, 2024, 12:57:11 PM3/20/24
to Peter Weinberger, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
Attention needed from Peter Weinberger

Kevin Burke added 1 comment

Commit Message
Line 13, Patchset 1 (Latest):Fixes: golang.org/go#66407
Kevin Burke . unresolved

Should be just golang/go#66407 or "Fixes #66407"

Open in Gerrit

Related details

Attention is currently required from:
  • Peter Weinberger
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not 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: comment
    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
    Gerrit-Change-Number: 573075
    Gerrit-PatchSet: 1
    Gerrit-Owner: Peter Weinberger <p...@google.com>
    Gerrit-Reviewer: Peter Weinberger <p...@google.com>
    Gerrit-CC: Kevin Burke <ke...@burke.dev>
    Gerrit-Attention: Peter Weinberger <p...@google.com>
    Gerrit-Comment-Date: Wed, 20 Mar 2024 16:57:08 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    unsatisfied_requirement
    open
    diffy

    Peter Weinberger (Gerrit)

    unread,
    Mar 20, 2024, 1:38:00 PM3/20/24
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
    Attention needed from Peter Weinberger

    Peter Weinberger uploaded new patchset

    Peter Weinberger 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:
    • Peter Weinberger
    Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not 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: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
    Gerrit-Change-Number: 573075
    Gerrit-PatchSet: 2
    unsatisfied_requirement
    open
    diffy

    Peter Weinberger (Gerrit)

    unread,
    Mar 20, 2024, 1:38:47 PM3/20/24
    to goph...@pubsubhelper.golang.org, Kevin Burke, Go LUCI, golang-co...@googlegroups.com
    Attention needed from Kevin Burke

    Peter Weinberger added 1 comment

    Kevin Burke . unresolved

    Should be just golang/go#66407 or "Fixes #66407"

    Peter Weinberger

    yes

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Kevin Burke
    Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not 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: comment
    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
    Gerrit-Change-Number: 573075
    Gerrit-PatchSet: 2
    Gerrit-Owner: Peter Weinberger <p...@google.com>
    Gerrit-Reviewer: Peter Weinberger <p...@google.com>
    Gerrit-CC: Kevin Burke <ke...@burke.dev>
    Gerrit-Attention: Kevin Burke <ke...@burke.dev>
    Gerrit-Comment-Date: Wed, 20 Mar 2024 17:38:43 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Kevin Burke <ke...@burke.dev>
    unsatisfied_requirement
    open
    diffy

    Peter Weinberger (Gerrit)

    unread,
    Mar 20, 2024, 3:59:51 PM3/20/24
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
    Attention needed from Kevin Burke and Peter Weinberger

    Peter Weinberger uploaded new patchset

    Peter Weinberger uploaded patch set #3 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:
    • Kevin Burke
    • Peter Weinberger
    Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not 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: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
    Gerrit-Change-Number: 573075
    Gerrit-PatchSet: 3
    Gerrit-Owner: Peter Weinberger <p...@google.com>
    Gerrit-Reviewer: Peter Weinberger <p...@google.com>
    Gerrit-CC: Kevin Burke <ke...@burke.dev>
    Gerrit-Attention: Peter Weinberger <p...@google.com>
    Gerrit-Attention: Kevin Burke <ke...@burke.dev>
    unsatisfied_requirement
    open
    diffy

    Peter Weinberger (Gerrit)

    unread,
    Mar 20, 2024, 4:23:11 PM3/20/24
    to goph...@pubsubhelper.golang.org, Go LUCI, Kevin Burke, golang-co...@googlegroups.com
    Attention needed from Kevin Burke

    Peter Weinberger added 1 comment

    Commit Message
    Kevin Burke . resolved

    Should be just golang/go#66407 or "Fixes #66407"

    Peter Weinberger

    yes

    Peter Weinberger

    Done

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Kevin Burke
    Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
      Gerrit-Change-Number: 573075
      Gerrit-PatchSet: 3
      Gerrit-Owner: Peter Weinberger <p...@google.com>
      Gerrit-Reviewer: Peter Weinberger <p...@google.com>
      Gerrit-CC: Kevin Burke <ke...@burke.dev>
      Gerrit-Attention: Kevin Burke <ke...@burke.dev>
      Gerrit-Comment-Date: Wed, 20 Mar 2024 20:23:07 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Comment-In-Reply-To: Peter Weinberger <p...@google.com>
      Comment-In-Reply-To: Kevin Burke <ke...@burke.dev>
      unsatisfied_requirement
      satisfied_requirement
      open
      diffy

      Robert Findley (Gerrit)

      unread,
      Mar 29, 2024, 10:05:39 AM3/29/24
      to Peter Weinberger, goph...@pubsubhelper.golang.org, Go LUCI, Kevin Burke, golang-co...@googlegroups.com
      Attention needed from Kevin Burke and Peter Weinberger

      Robert Findley added 10 comments

      File gopls/internal/test/integration/misc/imports_test.go
      Line 101, Patchset 3 (Latest): env.SaveBuffer("a.go")
      Robert Findley . unresolved

      Is this Save necessary? I don't see why it would be.

      Line 103, Patchset 3 (Latest): env.Await(Diagnostics(ForFile("a.go")))
      Robert Findley . unresolved

      Shouldn't the diagnostics go away after a call to OrganizeImports?

      I suspect that this should be `env.AfterChange(NoDiagnostics())`, which asserts that once gopls is done diagnosing the OrganizeImports changes, there are no diagnostics for any file.

      Right now, it looks like this is a racy assertion that there *are* diagnostics, which only succeeds because gopls hasn't yet processed the imports change.

      File internal/imports/fix.go
      Line 306, Patchset 3 (Latest): if v := path.Base(nm); v[0] == 'v' {
      Robert Findley . unresolved

      Nit: better to make this a pure function and not worry about it: `len(v) > 0 && v[0] == 'v'`.

      ```suggestion
      if v := path.Base(nm); len(v) > 0 && v[0] == 'v' {
      ```
      Line 308, Patchset 3 (Latest): if len(v) < len(nm) {
      Robert Findley . unresolved

      Use path.Split?

      Line 310, Patchset 3 (Latest): return path.Base(xnm)
      Robert Findley . unresolved

      Why are we returning a base path here? Below, we're returning nm unmodified. Is this function just meant to equate rand/v2 and rand? I.e. strings with exactly one '/'? If so, I don't think it should be necessary -- see below comment in importIdentifier.

      Line 326, Patchset 3 (Latest): return withoutVersion(known.name)
      Robert Findley . unresolved

      packageInfo.name is documented to be the real package name, if known. Therefore, we shouldn't have to call withoutVersion here. Did you observe that this was necessary? If so, there must be a bug elsewhere.

      Line 1074, Patchset 3 (Latest): ans := path.Base(nm)

      if ans[0] == 'v' {
      if _, err := strconv.Atoi(ans[1:]); err == nil {
      ix := strings.LastIndex(nm, ans)

      more := path.Base(nm[:ix])
      ans = path.Join(more, ans)
      }
      }
      return ans
      Robert Findley . unresolved

      Use path.Split, and handle the degenerate case of an empty string.

      Line 1092, Patchset 3 (Latest): &packageInfo{name: localbase(pkg), exports: exports}) // PJW: Base is not right (math/v2)
      Robert Findley . unresolved

      Is this true? I thought localbase fixed that.

      File internal/imports/fix_test.go
      Line 1147, Patchset 3 (Latest): name: "cryptorand_preferred_easy_impossible",
      Robert Findley . resolved

      I don't understand this test name. Is it supposed to assert that crypto/rand is preferred? Clearly, it is not! Or is it saying that it would be nice, but impossible, to prefer crypto/rand?

      Line 1156, Patchset 3 (Latest):var _ = rand.NewZipf
      Robert Findley . unresolved

      Please add a test where we prefer the old, deprecated rand (by using rand.Read, which doesn't exist in rand/v2, for example).

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Kevin Burke
      • Peter Weinberger
      Submit Requirements:
        • requirement is not satisfiedCode-Review
        • requirement is not satisfiedNo-Unresolved-Comments
        • requirement is not satisfiedReview-Enforcement
        • requirement satisfiedTryBots-Pass
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: tools
        Gerrit-Branch: master
        Gerrit-Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
        Gerrit-Change-Number: 573075
        Gerrit-PatchSet: 3
        Gerrit-Owner: Peter Weinberger <p...@google.com>
        Gerrit-Reviewer: Peter Weinberger <p...@google.com>
        Gerrit-Reviewer: Robert Findley <rfin...@google.com>
        Gerrit-CC: Kevin Burke <ke...@burke.dev>
        Gerrit-Attention: Peter Weinberger <p...@google.com>
        Gerrit-Attention: Kevin Burke <ke...@burke.dev>
        Gerrit-Comment-Date: Fri, 29 Mar 2024 14:05:30 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        unsatisfied_requirement
        satisfied_requirement
        open
        diffy

        Peter Weinberger (Gerrit)

        unread,
        Mar 29, 2024, 3:45:17 PM3/29/24
        to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
        Attention needed from Kevin Burke and Peter Weinberger

        Peter Weinberger uploaded new patchset

        Peter Weinberger uploaded patch set #4 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:
        • Kevin Burke
        • Peter Weinberger
        Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not 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: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
          Gerrit-Change-Number: 573075
          Gerrit-PatchSet: 4
          unsatisfied_requirement
          open
          diffy

          Peter Weinberger (Gerrit)

          unread,
          Mar 29, 2024, 4:03:36 PM3/29/24
          to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
          Attention needed from Robert Findley

          Peter Weinberger added 9 comments

          File gopls/internal/test/integration/misc/imports_test.go
          Line 101, Patchset 3: env.SaveBuffer("a.go")
          Robert Findley . resolved

          Is this Save necessary? I don't see why it would be.

          Peter Weinberger

          Done

          Line 103, Patchset 3: env.Await(Diagnostics(ForFile("a.go")))
          Robert Findley . resolved

          Shouldn't the diagnostics go away after a call to OrganizeImports?

          I suspect that this should be `env.AfterChange(NoDiagnostics())`, which asserts that once gopls is done diagnosing the OrganizeImports changes, there are no diagnostics for any file.

          Right now, it looks like this is a racy assertion that there *are* diagnostics, which only succeeds because gopls hasn't yet processed the imports change.

          Peter Weinberger

          Well there's a problem. go.mod has go1.21, and rand/v2 is only available for g1.22. But if go.mod is changed to go1.22, then tests fail with

                  runner.go:208: closing the sandbox: error(s) cleaning sandbox: cleaning modcache: go command failed (stdout: ) (stderr: go: downloading go1.22 (darwin/arm64)
          go: download go1.22 for darwin/arm64: toolchain not available

          So in this particular test, we expect diagnostics.

          I don't see what else to do without A) knowing what version of Go the user's code expects, and B) the dependence of stdlib symbols on go version.

          File internal/imports/fix.go
          Line 306, Patchset 3: if v := path.Base(nm); v[0] == 'v' {
          Robert Findley . resolved

          Nit: better to make this a pure function and not worry about it: `len(v) > 0 && v[0] == 'v'`.

          ```suggestion
          if v := path.Base(nm); len(v) > 0 && v[0] == 'v' {
          ```
          Peter Weinberger

          path.Base() never returns "", but the change avoids readers having to know that.

          Line 308, Patchset 3: if len(v) < len(nm) {
          Robert Findley . resolved

          Use path.Split?

          Peter Weinberger

          I do not see where path.Split helps. path.Base removes trailing /s but path.Split does not.

          Line 310, Patchset 3: return path.Base(xnm)
          Robert Findley . resolved

          Why are we returning a base path here? Below, we're returning nm unmodified. Is this function just meant to equate rand/v2 and rand? I.e. strings with exactly one '/'? If so, I don't think it should be necessary -- see below comment in importIdentifier.

          Peter Weinberger

          path.Base does canonicalization, so no one has to try to prove that there aren't repeated slashes in an inconvenient place in nm.

          Line 326, Patchset 3: return withoutVersion(known.name)
          Robert Findley . resolved

          packageInfo.name is documented to be the real package name, if known. Therefore, we shouldn't have to call withoutVersion here. Did you observe that this was necessary? If so, there must be a bug elsewhere.

          Peter Weinberger

          I don't know what "real package name" means. The test fails without this code. If the name is "math/rand/v2", the code needs to return "math/rand".

          Line 1074, Patchset 3: ans := path.Base(nm)

          if ans[0] == 'v' {
          if _, err := strconv.Atoi(ans[1:]); err == nil {
          ix := strings.LastIndex(nm, ans)
          more := path.Base(nm[:ix])
          ans = path.Join(more, ans)
          }
          }
          return ans
          Robert Findley . resolved

          Use path.Split, and handle the degenerate case of an empty string.

          Peter Weinberger

          It's better not to have to worry about trailing slashes. mod.go:724 is, I believe, incorrect for that reason.

          Line 1092, Patchset 3: &packageInfo{name: localbase(pkg), exports: exports}) // PJW: Base is not right (math/v2)
          Robert Findley . resolved

          Is this true? I thought localbase fixed that.

          Peter Weinberger

          The comment meant that path.Base() is not correct. Removed.

          File internal/imports/fix_test.go
          Line 1156, Patchset 3:var _ = rand.NewZipf
          Robert Findley . resolved

          Please add a test where we prefer the old, deprecated rand (by using rand.Read, which doesn't exist in rand/v2, for example).

          Peter Weinberger

          Read would give us crypt/rand. But Int63 works. I added such a test in fix_test.go right next to the test for the new behavior.

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Robert Findley
          Submit Requirements:
            • requirement is not satisfiedCode-Review
            • requirement satisfiedNo-Unresolved-Comments
            • requirement is not satisfiedReview-Enforcement
            • requirement satisfiedTryBots-Pass
            Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
            Gerrit-MessageType: comment
            Gerrit-Project: tools
            Gerrit-Branch: master
            Gerrit-Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
            Gerrit-Change-Number: 573075
            Gerrit-PatchSet: 4
            Gerrit-Owner: Peter Weinberger <p...@google.com>
            Gerrit-Reviewer: Peter Weinberger <p...@google.com>
            Gerrit-Reviewer: Robert Findley <rfin...@google.com>
            Gerrit-Attention: Robert Findley <rfin...@google.com>
            Gerrit-Comment-Date: Fri, 29 Mar 2024 20:03:31 +0000
            Gerrit-HasComments: Yes
            Gerrit-Has-Labels: No
            Comment-In-Reply-To: Robert Findley <rfin...@google.com>
            unsatisfied_requirement
            satisfied_requirement
            open
            diffy

            Robert Findley (Gerrit)

            unread,
            Apr 2, 2024, 5:00:48 PM4/2/24
            to Peter Weinberger, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
            Attention needed from Peter Weinberger

            Robert Findley added 5 comments

            File gopls/internal/test/integration/misc/imports_test.go
            Line 103, Patchset 3: env.Await(Diagnostics(ForFile("a.go")))
            Robert Findley . unresolved

            Shouldn't the diagnostics go away after a call to OrganizeImports?

            I suspect that this should be `env.AfterChange(NoDiagnostics())`, which asserts that once gopls is done diagnosing the OrganizeImports changes, there are no diagnostics for any file.

            Right now, it looks like this is a racy assertion that there *are* diagnostics, which only succeeds because gopls hasn't yet processed the imports change.

            Peter Weinberger

            Well there's a problem. go.mod has go1.21, and rand/v2 is only available for g1.22. But if go.mod is changed to go1.22, then tests fail with

                    runner.go:208: closing the sandbox: error(s) cleaning sandbox: cleaning modcache: go command failed (stdout: ) (stderr: go: downloading go1.22 (darwin/arm64)
            go: download go1.22 for darwin/arm64: toolchain not available

            So in this particular test, we expect diagnostics.

            I don't see what else to do without A) knowing what version of Go the user's code expects, and B) the dependence of stdlib symbols on go version.

            Robert Findley

            Do you mean that this test fails on the Go 1.21 builders? If that's the case, you can just add a `testenv.NeedsGo1Point(t, 22)` to only run this test on Go 1.22+, which is fine.

            In either case, we always try to use env.AfterChange rather than env.Await, since the latter is unbounded. If we know that the expected diagnostics should be present after all pending changes have been diagnosed, AfterChange is the API to use.

            File internal/imports/fix.go
            Line 306, Patchset 3: if v := path.Base(nm); v[0] == 'v' {
            Robert Findley . resolved

            Nit: better to make this a pure function and not worry about it: `len(v) > 0 && v[0] == 'v'`.

            ```suggestion
            if v := path.Base(nm); len(v) > 0 && v[0] == 'v' {
            ```
            Peter Weinberger

            path.Base() never returns "", but the change avoids readers having to know that.

            Robert Findley

            Aha, I thought it would return "" for the empty input. Thanks.

            Line 326, Patchset 3: return withoutVersion(known.name)
            Robert Findley . unresolved

            packageInfo.name is documented to be the real package name, if known. Therefore, we shouldn't have to call withoutVersion here. Did you observe that this was necessary? If so, there must be a bug elsewhere.

            Peter Weinberger

            I don't know what "real package name" means. The test fails without this code. If the name is "math/rand/v2", the code needs to return "math/rand".

            Robert Findley

            "real package name" is quoted from the doc string for packageInfo. I assumed it meant the package name defined by the `package <name>` clause in each package file. But that appears to be an inaccurate comment. Looking at the code, I see that in addStdLibCandidates, it is set to path.Base.

            I think we should fix the code to record the correct package name for known package. Can you see if that is feasible?

            Line 1074, Patchset 3: ans := path.Base(nm)
            if ans[0] == 'v' {
            if _, err := strconv.Atoi(ans[1:]); err == nil {
            ix := strings.LastIndex(nm, ans)
            more := path.Base(nm[:ix])
            ans = path.Join(more, ans)
            }
            }
            return ans
            Robert Findley . resolved

            Use path.Split, and handle the degenerate case of an empty string.

            Peter Weinberger

            It's better not to have to worry about trailing slashes. mod.go:724 is, I believe, incorrect for that reason.

            Robert Findley

            Ack.

            File internal/imports/fix_test.go
            Line 1156, Patchset 3:var _ = rand.NewZipf
            Robert Findley . unresolved

            Please add a test where we prefer the old, deprecated rand (by using rand.Read, which doesn't exist in rand/v2, for example).

            Peter Weinberger

            Read would give us crypt/rand. But Int63 works. I added such a test in fix_test.go right next to the test for the new behavior.

            Robert Findley

            I think this test wasn't added? I don't see a diff between the patchsets.

            Open in Gerrit

            Related details

            Attention is currently required from:
            • Peter Weinberger
            Submit Requirements:
              • requirement is not satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement is not satisfiedReview-Enforcement
              • requirement satisfiedTryBots-Pass
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: comment
              Gerrit-Project: tools
              Gerrit-Branch: master
              Gerrit-Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
              Gerrit-Change-Number: 573075
              Gerrit-PatchSet: 4
              Gerrit-Owner: Peter Weinberger <p...@google.com>
              Gerrit-Reviewer: Peter Weinberger <p...@google.com>
              Gerrit-Reviewer: Robert Findley <rfin...@google.com>
              Gerrit-Attention: Peter Weinberger <p...@google.com>
              Gerrit-Comment-Date: Tue, 02 Apr 2024 21:00:42 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: No
              Comment-In-Reply-To: Peter Weinberger <p...@google.com>
              Comment-In-Reply-To: Robert Findley <rfin...@google.com>
              unsatisfied_requirement
              satisfied_requirement
              open
              diffy

              Peter Weinberger (Gerrit)

              unread,
              Apr 6, 2024, 10:27:13 AM4/6/24
              to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
              Attention needed from Peter Weinberger

              Peter Weinberger uploaded new patchset

              Peter Weinberger uploaded patch set #5 to this change.
              Following approvals got outdated and were removed:
              • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI

              Related details

              Attention is currently required from:
              • Peter Weinberger
              Submit Requirements:
                • requirement is not satisfiedCode-Review
                • requirement is not 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: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
                Gerrit-Change-Number: 573075
                Gerrit-PatchSet: 5
                unsatisfied_requirement
                open
                diffy

                Peter Weinberger (Gerrit)

                unread,
                Apr 6, 2024, 11:43:51 AM4/6/24
                to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
                Attention needed from Robert Findley

                Peter Weinberger added 3 comments

                File gopls/internal/test/integration/misc/imports_test.go
                Line 103, Patchset 3: env.Await(Diagnostics(ForFile("a.go")))
                Robert Findley . resolved

                Shouldn't the diagnostics go away after a call to OrganizeImports?

                I suspect that this should be `env.AfterChange(NoDiagnostics())`, which asserts that once gopls is done diagnosing the OrganizeImports changes, there are no diagnostics for any file.

                Right now, it looks like this is a racy assertion that there *are* diagnostics, which only succeeds because gopls hasn't yet processed the imports change.

                Peter Weinberger

                Well there's a problem. go.mod has go1.21, and rand/v2 is only available for g1.22. But if go.mod is changed to go1.22, then tests fail with

                        runner.go:208: closing the sandbox: error(s) cleaning sandbox: cleaning modcache: go command failed (stdout: ) (stderr: go: downloading go1.22 (darwin/arm64)
                go: download go1.22 for darwin/arm64: toolchain not available

                So in this particular test, we expect diagnostics.

                I don't see what else to do without A) knowing what version of Go the user's code expects, and B) the dependence of stdlib symbols on go version.

                Robert Findley

                Do you mean that this test fails on the Go 1.21 builders? If that's the case, you can just add a `testenv.NeedsGo1Point(t, 22)` to only run this test on Go 1.22+, which is fine.

                In either case, we always try to use env.AfterChange rather than env.Await, since the latter is unbounded. If we know that the expected diagnostics should be present after all pending changes have been diagnosed, AfterChange is the API to use.

                Peter Weinberger

                I added some explanatory comments. a.go will have an error because its module is go1.21, which is too early for math/rand/v2, but is will get the 'right' import. (remembering that imports has no way of managing go version, but it would get an error without the import too) b.go will get just mat/rand because it uses a function from that package.

                And changed to AfterChange()

                File internal/imports/fix.go
                Line 326, Patchset 3: return withoutVersion(known.name)
                Robert Findley . resolved

                packageInfo.name is documented to be the real package name, if known. Therefore, we shouldn't have to call withoutVersion here. Did you observe that this was necessary? If so, there must be a bug elsewhere.

                Peter Weinberger

                I don't know what "real package name" means. The test fails without this code. If the name is "math/rand/v2", the code needs to return "math/rand".

                Robert Findley

                "real package name" is quoted from the doc string for packageInfo. I assumed it meant the package name defined by the `package <name>` clause in each package file. But that appears to be an inaccurate comment. Looking at the code, I see that in addStdLibCandidates, it is set to path.Base.

                I think we should fix the code to record the correct package name for known package. Can you see if that is feasible?

                Peter Weinberger

                I think that should be a separate issue and CL.

                File internal/imports/fix_test.go
                Line 1156, Patchset 3:var _ = rand.NewZipf
                Robert Findley . resolved

                Please add a test where we prefer the old, deprecated rand (by using rand.Read, which doesn't exist in rand/v2, for example).

                Peter Weinberger

                Read would give us crypt/rand. But Int63 works. I added such a test in fix_test.go right next to the test for the new behavior.

                Robert Findley

                I think this test wasn't added? I don't see a diff between the patchsets.

                Peter Weinberger

                The new test is in imports_test.go.

                Open in Gerrit

                Related details

                Attention is currently required from:
                • Robert Findley
                Submit Requirements:
                  • requirement is not satisfiedCode-Review
                  • requirement satisfiedNo-Unresolved-Comments
                  • requirement is not satisfiedReview-Enforcement
                  • requirement satisfiedTryBots-Pass
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: comment
                  Gerrit-Project: tools
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
                  Gerrit-Change-Number: 573075
                  Gerrit-PatchSet: 5
                  Gerrit-Owner: Peter Weinberger <p...@google.com>
                  Gerrit-Reviewer: Peter Weinberger <p...@google.com>
                  Gerrit-Reviewer: Robert Findley <rfin...@google.com>
                  Gerrit-Attention: Robert Findley <rfin...@google.com>
                  Gerrit-Comment-Date: Sat, 06 Apr 2024 15:43:45 +0000
                  unsatisfied_requirement
                  satisfied_requirement
                  open
                  diffy

                  Robert Findley (Gerrit)

                  unread,
                  Apr 8, 2024, 10:40:23 AM4/8/24
                  to Peter Weinberger, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
                  Attention needed from Peter Weinberger

                  Robert Findley voted and added 2 comments

                  Votes added by Robert Findley

                  Code-Review+2

                  2 comments

                  File internal/imports/fix.go
                  Line 1101, Patchset 5 (Latest): // but we have no way of figuring out what the user is using
                  Robert Findley . unresolved

                  I think we should promote this to a TODO: we could certainly capture the toolchain version when initializing the process env, and with all the problems we've had with forward/backward compatibility, it's probably something we want to do. WDYT?

                  Line 1098, Patchset 5 (Latest): // Make sure we try crypto/rand before math/rand as both have Int()
                  add("crypto/rand")
                  // if the user's no later than go1.21, this should be "math/rand"
                  // but we have no way of figuring out what the user is using
                  add("math/rand/v2")
                  Robert Findley . unresolved

                  Based on the comment on line 1098, the order of calls to addCandidate influence the chosen imports. So perhaps add
                  // ...and try math/rand/v2 before math/rand, for overlapping APIs.

                  Open in Gerrit

                  Related details

                  Attention is currently required from:
                  • Peter Weinberger
                  Submit Requirements:
                  • requirement satisfiedCode-Review
                  • requirement is not satisfiedNo-Unresolved-Comments
                  • requirement satisfiedReview-Enforcement
                  • requirement satisfiedTryBots-Pass
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: comment
                  Gerrit-Project: tools
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
                  Gerrit-Change-Number: 573075
                  Gerrit-PatchSet: 5
                  Gerrit-Owner: Peter Weinberger <p...@google.com>
                  Gerrit-Reviewer: Peter Weinberger <p...@google.com>
                  Gerrit-Reviewer: Robert Findley <rfin...@google.com>
                  Gerrit-Attention: Peter Weinberger <p...@google.com>
                  Gerrit-Comment-Date: Mon, 08 Apr 2024 14:40:19 +0000
                  Gerrit-HasComments: Yes
                  Gerrit-Has-Labels: Yes
                  satisfied_requirement
                  unsatisfied_requirement
                  open
                  diffy

                  Peter Weinberger (Gerrit)

                  unread,
                  Apr 8, 2024, 10:53:24 AM4/8/24
                  to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
                  Attention needed from Peter Weinberger

                  Peter Weinberger uploaded new patchset

                  Peter Weinberger uploaded patch set #6 to this change.
                  Following approvals got outdated and were removed:
                  • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI

                  Related details

                  Attention is currently required from:
                  • Peter Weinberger
                  Submit Requirements:
                  • requirement satisfiedCode-Review
                  • requirement is not satisfiedLegacy-TryBots-Pass
                  • requirement is not satisfiedNo-Unresolved-Comments
                  • requirement 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: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
                  Gerrit-Change-Number: 573075
                  Gerrit-PatchSet: 6
                  satisfied_requirement
                  unsatisfied_requirement
                  open
                  diffy

                  Peter Weinberger (Gerrit)

                  unread,
                  Apr 8, 2024, 11:07:03 AM4/8/24
                  to goph...@pubsubhelper.golang.org, Gopher Robot, Robert Findley, Go LUCI, golang-co...@googlegroups.com

                  Peter Weinberger added 2 comments

                  File internal/imports/fix.go
                  Line 1101, Patchset 5: // but we have no way of figuring out what the user is using
                  Robert Findley . resolved

                  I think we should promote this to a TODO: we could certainly capture the toolchain version when initializing the process env, and with all the problems we've had with forward/backward compatibility, it's probably something we want to do. WDYT?

                  Peter Weinberger

                  That would be a fairly substantial change, but I added the comment.

                  Line 1098, Patchset 5: // Make sure we try crypto/rand before math/rand as both have Int()

                  add("crypto/rand")
                  // if the user's no later than go1.21, this should be "math/rand"
                  // but we have no way of figuring out what the user is using
                  add("math/rand/v2")
                  Robert Findley . resolved

                  Based on the comment on line 1098, the order of calls to addCandidate influence the chosen imports. So perhaps add
                  // ...and try math/rand/v2 before math/rand, for overlapping APIs.

                  Peter Weinberger

                  I changed the comment.

                  Open in Gerrit

                  Related details

                  Attention set is empty
                  Submit Requirements:
                  • requirement satisfiedCode-Review
                  • requirement satisfiedLegacy-TryBots-Pass
                  • requirement satisfiedNo-Unresolved-Comments
                  • requirement satisfiedReview-Enforcement
                  • requirement is not satisfiedTryBots-Pass
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: comment
                  Gerrit-Project: tools
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
                  Gerrit-Change-Number: 573075
                  Gerrit-PatchSet: 6
                  Gerrit-Owner: Peter Weinberger <p...@google.com>
                  Gerrit-Reviewer: Gopher Robot <go...@golang.org>
                  Gerrit-Reviewer: Peter Weinberger <p...@google.com>
                  Gerrit-Reviewer: Robert Findley <rfin...@google.com>
                  Gerrit-Comment-Date: Mon, 08 Apr 2024 15:06:54 +0000
                  Gerrit-HasComments: Yes
                  Gerrit-Has-Labels: No
                  Comment-In-Reply-To: Robert Findley <rfin...@google.com>
                  satisfied_requirement
                  unsatisfied_requirement
                  open
                  diffy

                  Peter Weinberger (Gerrit)

                  unread,
                  Apr 10, 2024, 7:52:50 PM4/10/24
                  to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Go LUCI, Gopher Robot, Robert Findley, golang-co...@googlegroups.com

                  Peter Weinberger submitted the change with unreviewed changes

                  Unreviewed changes

                  5 is the latest approved patch-set.
                  The change was submitted with unreviewed changes in the following files:

                  ```
                  The name of the file: internal/imports/fix.go
                  Insertions: 3, Deletions: 1.

                  @@ -1010,8 +1010,10 @@
                  // already know the view type.
                  if len(e.Env["GOMOD"]) == 0 && len(e.Env["GOWORK"]) == 0 {
                  e.resolver = newGopathResolver(e)
                  + } else if r, err := newModuleResolver(e, e.ModCache); err != nil {
                  + e.resolverErr = err
                  } else {
                  - e.resolver, e.resolverErr = newModuleResolver(e, e.ModCache)
                  + e.resolver = Resolver(r)
                  }
                  }

                  @@ -1095,10 +1097,12 @@

                  }
                  for left := range refs {
                  if left == "rand" {
                  -			// Make sure we try crypto/rand before math/rand as both have Int()
                  + // Make sure we try crypto/rand before any version of math/rand as both have Int()
                  + // and our policy is to recommend crypto

                  add("crypto/rand")
                  // if the user's no later than go1.21, this should be "math/rand"
                  // but we have no way of figuring out what the user is using
                  +			// TODO: investigate using the toolchain version to disambiguate in the stdlib
                  add("math/rand/v2")
                  continue
                  }
                  ```

                  Change information

                  Commit message:
                  imports: prefer math/rand/v2 over math/rand

                  When a program refers to 'rand.Float64()' without an import statement,
                  import math/rand/v2 is the better answer.
                  Fixes: golang/go#66407
                  Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
                  Reviewed-by: Robert Findley <rfin...@google.com>
                  Files:
                  • M gopls/internal/test/integration/misc/imports_test.go
                  • M internal/imports/fix.go
                  • M internal/imports/fix_test.go
                  Change size: M
                  Delta: 3 files changed, 81 insertions(+), 6 deletions(-)
                  Branch: refs/heads/master
                  Submit Requirements:
                  • requirement satisfiedCode-Review: +2 by Robert Findley
                  • requirement satisfiedTryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
                  Open in Gerrit
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: merged
                  Gerrit-Project: tools
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I92709c335b61aa10dd49ce2e5336ea233d8f9af8
                  Gerrit-Change-Number: 573075
                  Gerrit-PatchSet: 8
                  open
                  diffy
                  satisfied_requirement
                  Reply all
                  Reply to author
                  Forward
                  0 new messages