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

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

このコミットは、Go言語のコンパイラ(当時の6g)における型可視性に関するバグ修正を目的としています。具体的には、パッケージ外部から参照されるべきではない型が誤って参照可能になっていた問題を修正し、テストケースが意図した通りに失敗する状態に戻すものです。

コミット

commit 793a97fbf6b1edd152ddd2bd73e5a6881018e019
Author: Ian Lance Taylor <iant@golang.org>
Date:   Wed Jan 21 12:52:22 2009 -0800

    Get this bug back to the intended state: bug1.go is making a
    reference to a type which should not be visible.  The test
    currently fails with 6g.
    
    R=rsc
    DELTA=7  (4 added, 0 deleted, 3 changed)
    OCL=23222
    CL=23225

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

https://github.com/golang/go/commit/793a97fbf6b1edd152ddd2bd73e5a6881018e019

元コミット内容

Get this bug back to the intended state: bug1.go is making a
reference to a type which should not be visible.  The test
currently fails with 6g.

R=rsc
DELTA=7  (4 added, 0 deleted, 3 changed)
OCL=23222
CL=23225

変更の背景

このコミットの背景には、Go言語のパッケージシステムにおける「可視性(visibility)」の原則があります。Goでは、識別子(変数、関数、型など)の名前が小文字で始まる場合、それはそのパッケージ内でのみ可視(unexported、非公開)となり、大文字で始まる場合はパッケージ外からも可視(exported、公開)となります。

このコミットが行われた当時、test/fixedbugs/bug083.dir/ディレクトリ内のテストケースは、本来パッケージ外から参照できないはずの型が誤って参照できてしまうというバグを検出するためのものでした。しかし、何らかの理由でこのテストケースが意図した通りに失敗しなくなっていたようです。

このコミットの目的は、そのテストケースを「意図した状態」、つまり非公開の型への不正な参照を検出し、コンパイルエラーとして失敗する状態に戻すことでした。これは、Goコンパイラ(当時の6g)が言語仕様に厳密に従って型可視性を強制していることを確認するための重要なステップです。

前提知識の解説

Go言語のパッケージと可視性

Go言語では、コードは「パッケージ」という単位で整理されます。各Goファイルは必ずpackage宣言を持ち、同じパッケージに属するファイルは同じ名前空間を共有します。

Goにおける識別子の可視性ルールは非常にシンプルかつ厳格です。

  • エクスポートされた識別子 (Exported Identifiers): 識別子の名前が大文字で始まる場合(例: MyType, MyFunction, MyVariable)、その識別子はパッケージ外から参照可能です。これは、他のパッケージがimport文を使ってそのパッケージをインポートした際に、その識別子を利用できることを意味します。
  • エクスポートされない識別子 (Unexported Identifiers): 識別子の名前が小文字で始まる場合(例: myType, myFunction, myVariable)、その識別子はそのパッケージ内でのみ参照可能です。パッケージ外からは直接参照することはできません。これは、内部実装の詳細を隠蔽し、APIの安定性を保つための重要なメカニズムです。

この可視性ルールは、構造体のフィールド名やメソッド名にも適用されます。例えば、構造体のフィールド名が小文字で始まる場合、そのフィールドはパッケージ外からはアクセスできません。

6gコンパイラ

6gは、Go言語の初期のコンパイラの一つです。Go言語の開発初期には、異なるアーキテクチャ(例: 8g for x86, 6g for amd64, 5g for ARM)に対応する複数のコンパイラが存在しました。これらはPlan 9 Cコンパイラツールチェーンをベースにしていました。

現在では、Goの公式コンパイラはgo tool compileコマンドを通じて利用される単一のコンパイラに統合されており、通常はユーザーが直接6gのような特定のコンパイラ名を意識することはありません。しかし、このコミットが作成された2009年当時は、6gが主要なコンパイラの一つとして使われており、そのコンパイラが言語仕様に沿って正しく動作するかどうかを検証するテストが重要でした。

このコミットは、6gがGoの型可視性ルールを正しく適用していることを確認するためのテストケースの修正であり、コンパイラの健全性を保つためのものです。

技術的詳細

このコミットの技術的詳細は、Go言語の型可視性ルールをテストケースに適用し、コンパイラがそれを正しく処理するかどうかを検証することにあります。

元のテストケースでは、bug0.goというファイルで定義された型が、bug1.goという別のパッケージのファイルから参照されていました。問題は、この参照がGoの可視性ルールに違反しているにもかかわらず、コンパイラがエラーを報告しなかった、あるいはテストがそのエラーを正しく検出できなかった点にありました。

コミットの変更内容は以下の通りです。

  1. bug0.go内の型名の変更: bug0.go内で定義されていた構造体型T0の名前をt0に変更しています。これにより、Goの可視性ルールに従い、t0bug0パッケージ内でのみ可視な(非公開の)型となります。
  2. bug0.go内の変数名の変更: T0型を持つ変数V0の名前もt0型を持つ変数V0に変更されています。これは型名の変更に伴う整合性のための変更です。
  3. bug1.go内の参照の修正: bug1.go内でbug0.T0として参照されていた部分をbug0.t0に変更しています。

この変更により、bug1.gobug0パッケージの非公開型であるt0を参照しようとすることになります。Goの言語仕様によれば、これはコンパイルエラーとなるべき動作です。コミットメッセージにある「The test currently fails with 6g.」という記述は、この変更によって6gコンパイラが期待通りにエラーを報告し、テストが失敗するようになったことを示しています。

これは、コンパイラが言語仕様に厳密に従って型可視性を強制していることを確認するための「回帰テスト」のような役割を果たします。もし将来的にコンパイラの変更によってこのテストがパスするようになった場合、それはコンパイラが型可視性ルールを誤って解釈している可能性を示唆することになります。

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

--- a/test/fixedbugs/bug083.dir/bug0.go
+++ b/test/fixedbugs/bug083.dir/bug0.go
@@ -4,7 +4,7 @@
 
  package bug0
 
 -type T0 struct {
 +type t0 struct {
  }
 
 -var V0 T0
 +var V0 t0
diff --git a/test/fixedbugs/bug083.dir/bug1.go b/test/fixedbugs/bug083.dir/bug1.go
index 32cda73b4f..ac6a73844d 100644
--- a/test/fixedbugs/bug083.dir/bug1.go
+++ b/test/fixedbugs/bug083.dir/bug1.go
@@ -6,4 +6,8 @@ package bug1
 
  import "bug0"
 
 -var v1 bug0.T0
 +// This is expected to fail--t0 is in package bug0 and should not be
 +// visible here in package bug1.  The test for failure is in
 +// ../bug083.go.
 +
 +var v1 bug0.t0

コアとなるコードの解説

test/fixedbugs/bug083.dir/bug0.go の変更

  • -type T0 struct { から +type t0 struct {:
    • 元のコードではT0という名前で構造体型が定義されていました。Goの命名規則では、大文字で始まる識別子は「エクスポートされた(公開された)」型となり、他のパッケージから参照可能です。
    • 変更後、型名がt0と小文字で始まるように修正されました。これにより、t0型はbug0パッケージ内でのみ可視な「エクスポートされない(非公開の)」型となります。
  • -var V0 T0 から +var V0 t0:
    • 型名T0の変更に伴い、その型を使用していた変数V0の宣言もt0型を使用するように更新されました。これは型名の変更に合わせた整合性のある修正です。

test/fixedbugs/bug083.dir/bug1.go の変更

  • -var v1 bug0.T0 から +var v1 bug0.t0:
    • 元のコードでは、bug1パッケージ内でbug0.T0という形でbug0パッケージのT0型を参照していました。T0は公開型であったため、この参照は合法でした。
    • 変更後、bug0.t0と参照が修正されました。bug0.goT0t0にリネームされ非公開型になったため、bug1パッケージからbug0.t0を参照しようとすると、Goの可視性ルールに違反し、コンパイルエラーとなることが期待されます。
  • コメントの追加:
    • 変更された行の上に新しいコメントが追加されています。
    • // This is expected to fail--t0 is in package bug0 and should not be
    • // visible here in package bug1. The test for failure is in
    • // ../bug083.go.
    • このコメントは、このコードがなぜコンパイルエラーになることが期待されるのか、その理由(t0bug0パッケージの非公開型であり、bug1パッケージからは見えないため)を明確に説明しています。また、このエラーを検出するテスト本体が../bug083.goにあることも示唆しています。

これらの変更により、テストケースはGoの型可視性ルールを厳密に検証する形になり、6gコンパイラが非公開型への不正な参照を正しく検出してエラーを報告するかどうかを確認できるようになりました。

関連リンク

  • Go言語のパッケージと可視性に関する公式ドキュメント(Go言語仕様):
  • Go言語の初期のコンパイラに関する情報(Goの歴史やツールチェーンについて):
    • https://go.dev/doc/go1.html (Go 1のリリースノートなどから、当時のツールチェーンの構成を推測できます)

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Go言語のソースコードリポジトリ(GitHub)
  • Go言語のパッケージと可視性に関する一般的な解説記事(Web検索結果)
  • Go言語の歴史に関する情報(Web検索結果)

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

このコミットは、Go言語のコンパイラ(当時の6g)における型可視性に関するバグ修正を目的としています。具体的には、パッケージ外部から参照されるべきではない型が誤って参照可能になっていた問題を修正し、テストケースが意図した通りに失敗する状態に戻すものです。

コミット

commit 793a97fbf6b1edd152ddd2bd73e5a6881018e019
Author: Ian Lance Taylor <iant@golang.org>
Date:   Wed Jan 21 12:52:22 2009 -0800

    Get this bug back to the intended state: bug1.go is making a
    reference to a type which should not be visible.  The test
    currently fails with 6g.
    
    R=rsc
    DELTA=7  (4 added, 0 deleted, 3 changed)
    OCL=23222
    CL=23225

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

https://github.com/golang/go/commit/793a97fbf6b1edd152ddd2bd73e5a6881018e019

元コミット内容

Get this bug back to the intended state: bug1.go is making a
reference to a type which should not be visible.  The test
currently fails with 6g.

R=rsc
DELTA=7  (4 added, 0 deleted, 3 changed)
OCL=23222
CL=23225

変更の背景

このコミットの背景には、Go言語のパッケージシステムにおける「可視性(visibility)」の原則があります。Goでは、識別子(変数、関数、型など)の名前が小文字で始まる場合、それはそのパッケージ内でのみ可視(unexported、非公開)となり、大文字で始まる場合はパッケージ外からも可視(exported、公開)となります。

このコミットが行われた当時、test/fixedbugs/bug083.dir/ディレクトリ内のテストケースは、本来パッケージ外から参照できないはずの型が誤って参照できてしまうというバグを検出するためのものでした。しかし、何らかの理由でこのテストケースが意図した通りに失敗しなくなっていたようです。

このコミットの目的は、そのテストケースを「意図した状態」、つまり非公開の型への不正な参照を検出し、コンパイルエラーとして失敗する状態に戻すことでした。これは、Goコンパイラ(当時の6g)が言語仕様に厳密に従って型可視性を強制していることを確認するための重要なステップです。

前提知識の解説

Go言語のパッケージと可視性

Go言語では、コードは「パッケージ」という単位で整理されます。各Goファイルは必ずpackage宣言を持ち、同じパッケージに属するファイルは同じ名前空間を共有します。

Goにおける識別子の可視性ルールは非常にシンプルかつ厳格です。

  • エクスポートされた識別子 (Exported Identifiers): 識別子の名前が大文字で始まる場合(例: MyType, MyFunction, MyVariable)、その識別子はパッケージ外から参照可能です。これは、他のパッケージがimport文を使ってそのパッケージをインポートした際に、その識別子を利用できることを意味します。
  • エクスポートされない識別子 (Unexported Identifiers): 識別子の名前が小文字で始まる場合(例: myType, myFunction, myVariable)、その識別子はそのパッケージ内でのみ参照可能です。パッケージ外からは直接参照することはできません。これは、内部実装の詳細を隠蔽し、APIの安定性を保つための重要なメカニズムです。

この可視性ルールは、構造体のフィールド名やメソッド名にも適用されます。例えば、構造体のフィールド名が小文字で始まる場合、そのフィールドはパッケージ外からはアクセスできません。

6gコンパイラ

6gは、Go言語の初期のコンパイラの一つです。Go言語の開発初期には、異なるアーキテクチャ(例: 8g for x86, 6g for amd64, 5g for ARM)に対応する複数のコンパイラが存在しました。これらはPlan 9 Cコンパイラツールチェーンをベースにしていました。

現在では、Goの公式コンパイラはgo tool compileコマンドを通じて利用される単一のコンパイラに統合されており、通常はユーザーが直接6gのような特定のコンパイラ名を意識することはありません。しかし、このコミットが作成された2009年当時は、6gが主要なコンパイラの一つとして使われており、そのコンパイラが言語仕様に沿って正しく動作するかどうかを検証するテストが重要でした。

このコミットは、6gがGoの型可視性ルールを正しく適用していることを確認するためのテストケースの修正であり、コンパイラの健全性を保つためのものです。

技術的詳細

このコミットの技術的詳細は、Go言語の型可視性ルールをテストケースに適用し、コンパイラがそれを正しく処理するかどうかを検証することにあります。

元のテストケースでは、bug0.goというファイルで定義された型が、bug1.goという別のパッケージのファイルから参照されていました。問題は、この参照がGoの可視性ルールに違反しているにもかかわらず、コンパイラがエラーを報告しなかった、あるいはテストがそのエラーを正しく検出できなかった点にありました。

コミットの変更内容は以下の通りです。

  1. bug0.go内の型名の変更: bug0.go内で定義されていた構造体型T0の名前をt0に変更しています。これにより、Goの可視性ルールに従い、t0bug0パッケージ内でのみ可視な(非公開の)型となります。
  2. bug0.go内の変数名の変更: T0型を持つ変数V0の名前もt0型を持つ変数V0に変更されています。これは型名の変更に伴う整合性のための変更です。
  3. bug1.go内の参照の修正: bug1.go内でbug0.T0として参照されていた部分をbug0.t0に変更しています。

この変更により、bug1.gobug0パッケージの非公開型であるt0を参照しようとすることになります。Goの言語仕様によれば、これはコンパイルエラーとなるべき動作です。コミットメッセージにある「The test currently fails with 6g.」という記述は、この変更によって6gコンパイラが期待通りにエラーを報告し、テストが失敗するようになったことを示しています。

これは、コンパイラが言語仕様に厳密に従って型可視性を強制していることを確認するための「回帰テスト」のような役割を果たします。もし将来的にコンパイラの変更によってこのテストがパスするようになった場合、それはコンパイラが型可視性ルールを誤って解釈している可能性を示唆することになります。

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

--- a/test/fixedbugs/bug083.dir/bug0.go
+++ b/test/fixedbugs/bug083.dir/bug0.go
@@ -4,7 +4,7 @@
 
  package bug0
 
 -type T0 struct {
 +type t0 struct {
  }
 
 -var V0 T0
 +var V0 t0
diff --git a/test/fixedbugs/bug083.dir/bug1.go b/test/fixedbugs/bug083.dir/bug1.go
index 32cda73b4f..ac6a73844d 100644
--- a/test/fixedbugs/bug083.dir/bug1.go
+++ b/test/fixedbugs/bug083.dir/bug1.go
@@ -6,4 +6,8 @@ package bug1
 
  import "bug0"
 
 -var v1 bug0.T0
 +// This is expected to fail--t0 is in package bug0 and should not be
 +// visible here in package bug1.  The test for failure is in
 +// ../bug083.go.
 +
 +var v1 bug0.t0

コアとなるコードの解説

test/fixedbugs/bug083.dir/bug0.go の変更

  • -type T0 struct { から +type t0 struct {:
    • 元のコードではT0という名前で構造体型が定義されていました。Goの命名規則では、大文字で始まる識別子は「エクスポートされた(公開された)」型となり、他のパッケージから参照可能です。
    • 変更後、型名がt0と小文字で始まるように修正されました。これにより、t0型はbug0パッケージ内でのみ可視な「エクスポートされない(非公開の)」型となります。
  • -var V0 T0 から +var V0 t0:
    • 型名T0の変更に伴い、その型を使用していた変数V0の宣言もt0型を使用するように更新されました。これは型名の変更に合わせた整合性のある修正です。

test/fixedbugs/bug083.dir/bug1.go の変更

  • -var v1 bug0.T0 から +var v1 bug0.t0:
    • 元のコードでは、bug1パッケージ内でbug0.T0という形でbug0パッケージのT0型を参照していました。T0は公開型であったため、この参照は合法でした。
    • 変更後、bug0.t0と参照が修正されました。bug0.goT0t0にリネームされ非公開型になったため、bug1パッケージからbug0.t0を参照しようとすると、Goの可視性ルールに違反し、コンパイルエラーとなることが期待されます。
  • コメントの追加:
    • 変更された行の上に新しいコメントが追加されています。
    • // This is expected to fail--t0 is in package bug0 and should not be
    • // visible here in package bug1. The test for failure is in
    • // ../bug083.go.
    • このコメントは、このコードがなぜコンパイルエラーになることが期待されるのか、その理由(t0bug0パッケージの非公開型であり、bug1パッケージからは見えないため)を明確に説明しています。また、このエラーを検出するテスト本体が../bug083.goにあることも示唆しています。

これらの変更により、テストケースはGoの型可視性ルールを厳密に検証する形になり、6gコンパイラが非公開型への不正な参照を正しく検出してエラーを報告するかどうかを確認できるようになりました。

関連リンク

  • Go言語のパッケージと可視性に関する公式ドキュメント(Go言語仕様):
  • Go言語の初期のコンパイラに関する情報(Goの歴史やツールチェーンについて):
    • https://go.dev/doc/go1.html (Go 1のリリースノートなどから、当時のツールチェーンの構成を推測できます)

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Go言語のソースコードリポジトリ(GitHub)
  • Go言語のパッケージと可視性に関する一般的な解説記事(Web検索結果)
  • Go言語の歴史に関する情報(Web検索結果)