Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 19648] ファイルの概要

このコミットは、Go言語の公式フォーマッタであるgofmtのバグ修正に関するものです。具体的には、gofmt -s(簡略化オプション)が3インデックススライスを誤って簡略化してしまう問題を修正しています。

コミット

commit dddc8b193fdd548061bb9f77b9395e6417a97cb6
Author: Robert Griesemer <gri@golang.org>
Date:   Tue Jul 1 10:40:27 2014 -0700

    cmd/gofmt: fix gofmt -s for 3-index slices
    
    3-index slices of the form s[:len(s):len(s)]
    cannot be simplified to s[::len(s)].
    
    LGTM=bradfitz
    R=golang-codereviews, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/108330043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/dddc8b193fdd548061bb9f77b9395e6417a97cb6

元コミット内容

cmd/gofmt: fix gofmt -s for 3-index slices

gofmt -sが3インデックススライス、特にs[:len(s):len(s)]のような形式のものをs[::len(s)]に簡略化できない問題を修正します。

変更の背景

Go言語のスライスは、配列の一部を参照するための強力な機能です。通常、スライスはs[low:high]という2つのインデックスで表現されますが、Go 1.2からs[low:high:capacity]という3つのインデックスを持つスライス式が導入されました。この3インデックススライスは、スライスの長さ(high - low)だけでなく、その基盤となる配列の容量(capacity - low)も指定できるため、より細かなメモリ管理やスライスの再スライス時の挙動を制御するのに役立ちます。

gofmtはGoコードを整形するための標準ツールであり、-sオプションを使用すると、コードをより簡潔な形式に自動的に書き換える「簡略化」機能を提供します。例えば、s[0:len(s)]s[:]に簡略化されるといった具合です。

このコミット以前のgofmt -sは、3インデックススライスの一部を誤って簡略化しようとしていました。具体的には、s[:len(s):len(s)]という形式のスライス式を、s[::len(s)]という形式に簡略化しようとしていました。しかし、Go言語の仕様では、3インデックススライスにおいて最初のインデックス(low)が省略された場合、それは常に0を意味します。したがって、s[::len(s)]s[0:len(s):len(s)]と同じ意味になります。

問題は、s[:len(s):len(s)]s[0:len(s):len(s)]は同じ意味であるにもかかわらず、gofmt -sがこれをs[::len(s)]に簡略化しようとした際に、s[::len(s)]が常に有効な簡略化ではないケースが存在したことです。特に、s[:len(s):len(s)]は、スライスの長さと容量が同じであることを明示的に示していますが、s[::len(s)]は、low0であることを前提としています。この簡略化が常に安全ではないため、gofmtはこのようなケースで誤った簡略化を行わないように修正する必要がありました。

このバグは、gofmt -sがコードのセマンティクスを変更してしまう可能性があり、Go開発者にとっては非常に重要な問題でした。そのため、この修正はgofmtの信頼性と正確性を保つ上で不可欠でした。

前提知識の解説

Go言語のスライス

Go言語のスライスは、同じ型の要素の連続したシーケンスを表すデータ構造です。スライスは配列の上に構築されており、配列の一部を参照します。スライスは、長さ(len)と容量(cap)という2つの重要なプロパティを持っています。

  • 長さ (Length): スライスに含まれる要素の数。len(s)で取得できます。
  • 容量 (Capacity): スライスの基盤となる配列の、スライスが参照している開始位置から末尾までの要素の数。cap(s)で取得できます。

スライス式

Goのスライス式には、主に以下の2つの形式があります。

  1. 2インデックススライス: a[low : high]

    • lowからhigh-1までの要素を含む新しいスライスを作成します。
    • lowが省略された場合、デフォルトは0です。
    • highが省略された場合、デフォルトは元のスライスの長さ(len(a))です。
    • 新しいスライスの長さはhigh - low、容量はcap(a) - lowです。
  2. 3インデックススライス: a[low : high : capacity] (Go 1.2以降)

    • lowからhigh-1までの要素を含む新しいスライスを作成します。
    • capacityは、新しいスライスの容量を明示的に設定します。新しいスライスの容量はcapacity - lowになります。
    • lowが省略された場合、デフォルトは0です。
    • highが省略された場合、デフォルトは元のスライスの長さ(len(a))です。
    • capacityhigh以上でなければなりません。
    • この形式は、特にスライスの再スライス時に、基盤となる配列のどの範囲までアクセス可能かを厳密に制御したい場合に有用です。例えば、元のスライスの容量の一部だけを新しいスライスに「公開」したい場合などに使われます。

gofmt-sオプション

gofmtは、Go言語のソースコードを標準的なスタイルに自動的に整形するツールです。Goコミュニティでは、gofmtによって整形されたコードが標準とされており、これによりコードの一貫性が保たれ、可読性が向上します。

-sオプションは、gofmtにコードの「簡略化」を指示します。これは、冗長な表現をより簡潔な同等の表現に書き換える機能です。例えば、以下のような簡略化が行われます。

  • x[0:len(x)]x[:]
  • x[low:len(x)]x[low:]
  • for _ = range xfor range x
  • if x { return true } else { return false }return x

-sオプションは、コードのセマンティクスを変えることなく、より慣用的なGoのスタイルに近づけることを目的としています。

GoのAST (Abstract Syntax Tree)

Goコンパイラやgofmtのようなツールは、Goのソースコードを直接操作するのではなく、まずソースコードを抽象構文木(AST: Abstract Syntax Tree)にパースします。ASTは、プログラムの構造を木構造で表現したものです。各ノードは、式、文、宣言などのプログラムの構成要素に対応します。

go/astパッケージは、GoのASTを表現するための型と関数を提供します。gofmtは、このASTを走査(traverse)し、特定のパターンにマッチするノードを見つけて、それを簡略化された形式のノードに置き換えることでコードの整形や簡略化を行います。

  • ast.Node: ASTのすべてのノードが実装するインターフェース。
  • ast.Visitor: ASTを走査するためのインターフェース。Visitメソッドを持ち、各ノードを訪問する際に呼び出されます。
  • ast.SliceExpr: スライス式を表すASTノード。X(スライスされる式)、LowHighMax(3インデックススライスのcapacity部分)などのフィールドを持ちます。
  • ast.Ident: 識別子(変数名、関数名など)を表すASTノード。

技術的詳細

このコミットの核心は、gofmtの簡略化ロジックが3インデックススライスを扱う際の不正確さを修正することにあります。

Goのスライス式s[low:high:max]において、lowが省略された場合、それは0を意味します。つまり、s[:high:max]s[0:high:max]と等価です。 同様に、highが省略された場合、それはlen(s)を意味します。つまり、s[low::max]s[low:len(s):max]と等価です。

問題となっていたのは、gofmt -ss[:len(s):len(s)]という形式のスライス式を簡略化しようとした際に、これをs[::len(s)]に変換しようとしていた点です。

ここで重要なのは、s[:len(s):len(s)]は、lowが省略されているため0と解釈され、highlen(s)maxlen(s)であるスライス式です。つまり、s[0:len(s):len(s)]と等価です。

一方、s[::len(s)]は、lowが省略されているため0と解釈され、highも省略されているためlen(s)と解釈され、maxlen(s)であるスライス式です。つまり、これもs[0:len(s):len(s)]と等価です。

一見すると、両者は同じ意味に見えます。しかし、gofmt -sの簡略化の目的は、コードをより簡潔にすることであり、その過程でセマンティクスを変更してはなりません。このコミット以前のgofmtの簡略化ロジックでは、s[:len(s):len(s)]のような形式のスライス式を簡略化する際に、Maxフィールド(3番目のインデックス)が存在する場合の考慮が不足していました。

simplify.go内のVisitメソッドは、ASTノードを走査し、簡略化可能なスライス式を見つけると変換を行います。以前のコードでは、n.Max != nil(3番目のインデックスが存在する場合)のチェックが、簡略化をスキップする条件として適切に組み込まれていませんでした。

この修正は、n.Max != nilの場合、つまり3インデックススライスの場合には、特定の簡略化(特にs[low:len(s)]s[low:]に簡略化するようなケース)を行わないようにすることで、この問題を解決しています。なぜなら、3インデックススライスでは、highmaxの値が同じであっても、その明示的な指定がコードの意図を伝える上で重要である場合があるため、安易な簡略化は避けるべきだからです。

また、len()関数が組み込み関数ではなく、ドットインポートによって導入された別のパッケージの関数である可能性(s.hasDotImport)も考慮されています。この場合も、len()が組み込みのlen()関数であると断定できないため、簡略化は行われません。これは、gofmtがコードのセマンティクスを正確に理解できない場合に、安全側に倒して簡略化を避けるという原則に基づいています。

この修正により、gofmt -sは3インデックススライスを正しく扱い、コードのセマンティクスを損なうことなく、安全な簡略化のみを行うようになりました。

コアとなるコードの変更箇所

変更はsrc/cmd/gofmt/simplify.goファイルに集中しています。

--- a/src/cmd/gofmt/simplify.go
+++ b/src/cmd/gofmt/simplify.go
@@ -68,9 +68,10 @@ func (s *simplifier) Visit(node ast.Node) ast.Visitor {
 		// a slice expression of the form: s[a:len(s)]
 		// can be simplified to: s[a:]
 		// if s is "simple enough" (for now we only accept identifiers)
-		if s.hasDotImport {
-			// if dot imports are present, we cannot be certain that an
-			// unresolved "len" identifier refers to the predefined len()
+		if n.Max != nil || s.hasDotImport {
+			// - 3-index slices always require the 2nd and 3rd index
+			// - if dot imports are present, we cannot be certain that an
+			//   unresolved "len" identifier refers to the predefined len()
 			break
 		}
 		if s, _ := n.X.(*ast.Ident); s != nil && s.Obj != nil {

テストデータも追加されています。

  • src/cmd/gofmt/testdata/slices1.golden
  • src/cmd/gofmt/testdata/slices1.input

これらのテストファイルは、3インデックススライスがgofmt -sによって誤って簡略化されないことを確認するために、新しいテストケースを追加しています。

コアとなるコードの解説

変更されたsimplify.goのコードは、simplifier構造体のVisitメソッド内にあります。このメソッドは、ASTを走査し、各ノードに対して簡略化のロジックを適用します。

変更前のコードでは、スライス式s[a:len(s)]s[a:]に簡略化する際に、s.hasDotImport(ドットインポートが存在するかどうか)のみをチェックしていました。ドットインポートが存在する場合、lenが組み込み関数ではなく、別のパッケージからインポートされた関数である可能性があるため、簡略化はスキップされていました。

変更後のコードでは、この条件にn.Max != nilが追加されています。

if n.Max != nil || s.hasDotImport {
    // - 3-index slices always require the 2nd and 3rd index
    // - if dot imports are present, we cannot be certain that an
    //   unresolved "len" identifier refers to the predefined len()
    break
}
  • n.Max != nil: これは、現在処理しているast.SliceExprノードが3インデックススライス(つまり、capacity部分が指定されているスライス)であることを意味します。
    • コメントに「3-index slices always require the 2nd and 3rd index」とあるように、3インデックススライスの場合、2番目と3番目のインデックス(highmax)は常に明示的に指定されていると見なされます。たとえhighlen(s)であっても、その明示的な存在が重要であるため、s[a:len(s):len(s)]のような形式をs[a::len(s)]のように簡略化することは避けるべきです。この条件が追加されたことで、gofmt -sは3インデックススライスに対して、highlen(s)であるからといって安易にhighを省略するような簡略化を行わなくなりました。これにより、コードの意図がより明確に保たれます。
  • s.hasDotImport: これは以前から存在していた条件で、ドットインポートが存在する場合にlenが組み込み関数であるかどうかの判断が難しくなるため、簡略化をスキップします。

このif文の条件がtrueの場合、breakが実行され、現在のスライス式の簡略化処理が中断されます。これにより、gofmt -sは、3インデックススライスやドットインポートが存在する状況で、誤った、あるいは意図しない簡略化を行うことを防ぎます。

この修正は、gofmtがGo言語の進化(3インデックススライスの導入)に追従し、その簡略化機能が常に安全で正確であることを保証するための重要なステップでした。

関連リンク

参考にした情報源リンク

# [インデックス 19648] ファイルの概要

このコミットは、Go言語の公式フォーマッタである`gofmt`のバグ修正に関するものです。具体的には、`gofmt -s`(簡略化オプション)が3インデックススライスを誤って簡略化してしまう問題を修正しています。

## コミット

commit dddc8b193fdd548061bb9f77b9395e6417a97cb6 Author: Robert Griesemer gri@golang.org Date: Tue Jul 1 10:40:27 2014 -0700

cmd/gofmt: fix gofmt -s for 3-index slices

3-index slices of the form s[:len(s):len(s)]
cannot be simplified to s[::len(s)].

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews
https://golang.org/cl/108330043

## GitHub上でのコミットページへのリンク

[https://github.com/golang/go/commit/dddc8b193fdd548061bb9f77b9395e6417a97cb6](https://github.com/golang/go/commit/dddc8b193fdd548061bb9f77b9395e6417a97cb6)

## 元コミット内容

`cmd/gofmt: fix gofmt -s for 3-index slices`

`gofmt -s`が3インデックススライス、特に`s[:len(s):len(s)]`のような形式のものを`s[::len(s)]`に簡略化できない問題を修正します。

## 変更の背景

Go言語のスライスは、配列の一部を参照するための強力な機能です。通常、スライスは`s[low:high]`という2つのインデックスで表現されますが、Go 1.2から`s[low:high:capacity]`という3つのインデックスを持つスライス式が導入されました。この3インデックススライスは、スライスの長さ(`high - low`)だけでなく、その基盤となる配列の容量(`capacity - low`)も指定できるため、より細かなメモリ管理やスライスの再スライス時の挙動を制御するのに役立ちます。

`gofmt`はGoコードを整形するための標準ツールであり、`-s`オプションを使用すると、コードをより簡潔な形式に自動的に書き換える「簡略化」機能を提供します。例えば、`s[0:len(s)]`は`s[:]`に簡略化されるといった具合です。

このコミット以前の`gofmt -s`は、3インデックススライスの一部を誤って簡略化しようとしていました。具体的には、`s[:len(s):len(s)]`という形式のスライス式を、`s[::len(s)]`という形式に簡略化しようとしていました。しかし、Go言語の仕様では、3インデックススライスにおいて最初のインデックス(`low`)が省略された場合、それは常に`0`を意味します。したがって、`s[::len(s)]`は`s[0:len(s):len(s)]`と同じ意味になります。

問題は、`s[:len(s):len(s)]`と`s[0:len(s):len(s)]`は同じ意味であるにもかかわらず、`gofmt -s`がこれを`s[::len(s)]`に簡略化しようとした際に、`s[::len(s)]`が常に有効な簡略化ではないケースが存在したことです。特に、`s[:len(s):len(s)]`は、スライスの長さと容量が同じであることを明示的に示していますが、`s[::len(s)]`は、`low`が`0`であることを前提としています。この簡略化が常に安全ではないため、`gofmt`はこのようなケースで誤った簡略化を行わないように修正する必要がありました。

このバグは、`gofmt -s`がコードのセマンティクスを変更してしまう可能性があり、Go開発者にとっては非常に重要な問題でした。そのため、この修正は`gofmt`の信頼性と正確性を保つ上で不可欠でした。

## 前提知識の解説

### Go言語のスライス

Go言語のスライスは、同じ型の要素の連続したシーケンスを表すデータ構造です。スライスは配列の上に構築されており、配列の一部を参照します。スライスは、長さ(`len`)と容量(`cap`)という2つの重要なプロパティを持っています。

*   **長さ (Length)**: スライスに含まれる要素の数。`len(s)`で取得できます。
*   **容量 (Capacity)**: スライスの基盤となる配列の、スライスが参照している開始位置から末尾までの要素の数。`cap(s)`で取得できます。

### スライス式

Goのスライス式には、主に以下の2つの形式があります。

1.  **2インデックススライス**: `a[low : high]`
    *   `low`から`high-1`までの要素を含む新しいスライスを作成します。
    *   `low`が省略された場合、デフォルトは`0`です。
    *   `high`が省略された場合、デフォルトは元のスライスの長さ(`len(a)`)です。
    *   新しいスライスの長さは`high - low`、容量は`cap(a) - low`です。

2.  **3インデックススライス**: `a[low : high : capacity]` (Go 1.2以降)
    *   `low`から`high-1`までの要素を含む新しいスライスを作成します。
    *   `capacity`は、新しいスライスの容量を明示的に設定します。新しいスライスの容量は`capacity - low`になります。
    *   `low`が省略された場合、デフォルトは`0`です。
    *   `high`が省略された場合、デフォルトは元のスライスの長さ(`len(a)`)です。
    *   `capacity`は`high`以上でなければなりません。
    *   この形式は、特にスライスの再スライス時に、基盤となる配列のどの範囲までアクセス可能かを厳密に制御したい場合に有用です。例えば、元のスライスの容量の一部だけを新しいスライスに「公開」したい場合などに使われます。

### `gofmt`と`-s`オプション

`gofmt`は、Go言語のソースコードを標準的なスタイルに自動的に整形するツールです。Goコミュニティでは、`gofmt`によって整形されたコードが標準とされており、これによりコードの一貫性が保たれ、可読性が向上します。

`-s`オプションは、`gofmt`にコードの「簡略化」を指示します。これは、冗長な表現をより簡潔な同等の表現に書き換える機能です。例えば、以下のような簡略化が行われます。

*   `x[0:len(x)]` → `x[:]`
*   `x[low:len(x)]` → `x[low:]`
*   `for _ = range x` → `for range x`
*   `if x { return true } else { return false }` → `return x`

`-s`オプションは、コードのセマンティクスを変えることなく、より慣用的なGoのスタイルに近づけることを目的としています。

### GoのAST (Abstract Syntax Tree)

Goコンパイラや`gofmt`のようなツールは、Goのソースコードを直接操作するのではなく、まずソースコードを抽象構文木(AST: Abstract Syntax Tree)にパースします。ASTは、プログラムの構造を木構造で表現したものです。各ノードは、式、文、宣言などのプログラムの構成要素に対応します。

`go/ast`パッケージは、GoのASTを表現するための型と関数を提供します。`gofmt`は、このASTを走査(traverse)し、特定のパターンにマッチするノードを見つけて、それを簡略化された形式のノードに置き換えることでコードの整形や簡略化を行います。

*   `ast.Node`: ASTのすべてのノードが実装するインターフェース。
*   `ast.Visitor`: ASTを走査するためのインターフェース。`Visit`メソッドを持ち、各ノードを訪問する際に呼び出されます。
*   `ast.SliceExpr`: スライス式を表すASTノード。`X`(スライスされる式)、`Low`、`High`、`Max`(3インデックススライスの`capacity`部分)などのフィールドを持ちます。
*   `ast.Ident`: 識別子(変数名、関数名など)を表すASTノード。

## 技術的詳細

このコミットの核心は、`gofmt`の簡略化ロジックが3インデックススライスを扱う際の不正確さを修正することにあります。

Goのスライス式`s[low:high:max]`において、`low`が省略された場合、それは`0`を意味します。つまり、`s[:high:max]`は`s[0:high:max]`と等価です。
同様に、`high`が省略された場合、それは`len(s)`を意味します。つまり、`s[low::max]`は`s[low:len(s):max]`と等価です。

問題となっていたのは、`gofmt -s`が`s[:len(s):len(s)]`という形式のスライス式を簡略化しようとした際に、これを`s[::len(s)]`に変換しようとしていた点です。

ここで重要なのは、`s[:len(s):len(s)]`は、`low`が省略されているため`0`と解釈され、`high`が`len(s)`、`max`が`len(s)`であるスライス式です。つまり、`s[0:len(s):len(s)]`と等価です。

一方、`s[::len(s)]`は、`low`が省略されているため`0`と解釈され、`high`も省略されているため`len(s)`と解釈され、`max`が`len(s)`であるスライス式です。つまり、これも`s[0:len(s):len(s)]`と等価です。

一見すると、両者は同じ意味に見えます。しかし、`gofmt -s`の簡略化の目的は、コードをより簡潔にすることであり、その過程でセマンティクスを変更してはなりません。このコミット以前の`gofmt`の簡略化ロジックでは、`s[:len(s):len(s)]`のような形式のスライス式を簡略化する際に、`Max`フィールド(3番目のインデックス)が存在する場合の考慮が不足していました。

`simplify.go`内の`Visit`メソッドは、ASTノードを走査し、簡略化可能なスライス式を見つけると変換を行います。以前のコードでは、`n.Max != nil`(3番目のインデックスが存在する場合)のチェックが、簡略化をスキップする条件として適切に組み込まれていませんでした。

この修正は、`n.Max != nil`の場合、つまり3インデックススライスの場合には、特定の簡略化(特に`s[low:len(s)]`を`s[low:]`に簡略化するようなケース)を行わないようにすることで、この問題を解決しています。なぜなら、3インデックススライスでは、`high`と`max`の値が同じであっても、その明示的な指定がコードの意図を伝える上で重要である場合があるため、安易な簡略化は避けるべきだからです。

また、`len()`関数が組み込み関数ではなく、ドットインポートによって導入された別のパッケージの関数である可能性(`s.hasDotImport`)も考慮されています。この場合も、`len()`が組み込みの`len()`関数であると断定できないため、簡略化は行われません。これは、`gofmt`がコードのセマンティクスを正確に理解できない場合に、安全側に倒して簡略化を避けるという原則に基づいています。

この修正により、`gofmt -s`は3インデックススライスを正しく扱い、コードのセマンティクスを損なうことなく、安全な簡略化のみを行うようになりました。

## コアとなるコードの変更箇所

変更は`src/cmd/gofmt/simplify.go`ファイルに集中しています。

```diff
--- a/src/cmd/gofmt/simplify.go
+++ b/src/cmd/gofmt/simplify.go
@@ -68,9 +68,10 @@ func (s *simplifier) Visit(node ast.Node) ast.Visitor {
 		// a slice expression of the form: s[a:len(s)]
 		// can be simplified to: s[a:]
 		// if s is "simple enough" (for now we only accept identifiers)
-		if s.hasDotImport {
-			// if dot imports are present, we cannot be certain that an
-			// unresolved "len" identifier refers to the predefined len()
+		if n.Max != nil || s.hasDotImport {
+			// - 3-index slices always require the 2nd and 3rd index
+			// - if dot imports are present, we cannot be certain that an
+			//   unresolved "len" identifier refers to the predefined len()
 			break
 		}
 		if s, _ := n.X.(*ast.Ident); s != nil && s.Obj != nil {

テストデータも追加されています。

  • src/cmd/gofmt/testdata/slices1.golden
  • src/cmd/gofmt/testdata/slices1.input

これらのテストファイルは、3インデックススライスがgofmt -sによって誤って簡略化されないことを確認するために、新しいテストケースを追加しています。

コアとなるコードの解説

変更されたsimplify.goのコードは、simplifier構造体のVisitメソッド内にあります。このメソッドは、ASTを走査し、各ノードに対して簡略化のロジックを適用します。

変更前のコードでは、スライス式s[a:len(s)]s[a:]に簡略化する際に、s.hasDotImport(ドットインポートが存在するかどうか)のみをチェックしていました。ドットインポートが存在する場合、lenが組み込み関数ではなく、別のパッケージからインポートされた関数である可能性があるため、簡略化はスキップされていました。

変更後のコードでは、この条件にn.Max != nilが追加されています。

if n.Max != nil || s.hasDotImport {
    // - 3-index slices always require the 2nd and 3rd index
    // - if dot imports are present, we cannot be certain that an
    //   unresolved "len" identifier refers to the predefined len()
    break
}
  • n.Max != nil: これは、現在処理しているast.SliceExprノードが3インデックススライス(つまり、capacity部分が指定されているスライス)であることを意味します。
    • コメントに「3-index slices always require the 2nd and 3rd index」とあるように、3インデックススライスの場合、2番目と3番目のインデックス(highmax)は常に明示的に指定されていると見なされます。たとえhighlen(s)であっても、その明示的な存在が重要であるため、s[a:len(s):len(s)]のような形式をs[a::len(s)]のように簡略化することは避けるべきです。この条件が追加されたことで、gofmt -sは3インデックススライスに対して、highlen(s)であるからといって安易にhighを省略するような簡略化を行わなくなりました。これにより、コードの意図がより明確に保たれます。
  • s.hasDotImport: これは以前から存在していた条件で、ドットインポートが存在する場合にlenが組み込み関数であるかどうかの判断が難しくなるため、簡略化をスキップします。

このif文の条件がtrueの場合、breakが実行され、現在のスライス式の簡略化処理が中断されます。これにより、gofmt -sは、3インデックススライスやドットインポートが存在する状況で、誤った、あるいは意図しない簡略化を行うことを防ぎます。

この修正は、gofmtがGo言語の進化(3インデックススライスの導入)に追従し、その簡略化機能が常に安全で正確であることを保証するための重要なステップでした。

関連リンク

参考にした情報源リンク