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

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

このコミットは、以前のコミット ea8b178f9b73 (CL 5375043) で導入された GOEXPERIMENT=reorg という実験的な機能を元に戻すものです。具体的には、Goコンパイラ (gc) 内のコードから、reorg というフラグと、それに関連するパッケージパスのリライトロジック (reorgpath 関数と reorgtab テーブル) を削除しています。

コミット

commit 1eadb89ee1d235d2e716cc7474976676db5f8bd4
Author: Russ Cox <rsc@golang.org>
Date:   Wed Nov 9 12:36:51 2011 -0500

    undo CL 5375043 / ea8b178f9b73
    
    Never lasts long.
    
    ««« original CL description
    gc: add GOEXPERIMENT=reorg
    
    This won't last long but may ease conversions.
    
    R=ken2
    CC=golang-dev
    https://golang.org/cl/5375043
    »»»
    
    R=ken2, ken
    CC=golang-dev
    https://golang.org/cl/5370043

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

https://github.com/golang/go/commit/1eadb89ee1d235d2e716cc7474976676db5f8bd4

元コミット内容

このコミットが元に戻している元のコミット (ea8b178f9b73 / CL 5375043) の内容は以下の通りです。

gc: add GOEXPERIMENT=reorg

This won't last long but may ease conversions.

これは、Goコンパイラ (gc) に GOEXPERIMENT=reorg という実験的なフラグを追加するものでした。このフラグは、パッケージのインポートパスの変換を容易にすることを目的としていましたが、一時的なものとして導入されたことが示唆されています。

変更の背景

このコミットの背景には、Go言語の標準ライブラリのパッケージ構造の再編成("reorganization")がありました。Go言語の初期段階では、一部のパッケージがより一般的なカテゴリの下に移動されるなど、パスが変更されることがありました。例えば、json パッケージが encoding/json に、http パッケージが net/http に移動するといった変更です。

このような大規模なパッケージパスの変更は、既存のコードベースに大きな影響を与えます。開発者は、新しいパッケージパスに合わせてコードを修正する必要がありました。GOEXPERIMENT=reorg は、この移行期間中の開発者の負担を軽減するために導入された一時的なメカニズムでした。このフラグを有効にすると、コンパイラが古いパッケージパスを新しいパスに自動的にマッピングすることで、コードの修正なしにコンパイルを可能にしようとしました。

しかし、コミットメッセージにある「Never lasts long. (長くは続かない)」という言葉が示すように、このような自動変換は一時的な回避策であり、最終的には開発者がコードを新しいパスに更新することが期待されていました。このコミットは、その一時的な期間が終了し、GOEXPERIMENT=reorg の機能が不要になったため、関連するコードを削除するものです。これは、Go言語の進化と、パッケージ構造の安定化に向けたステップと見なすことができます。

前提知識の解説

Go言語のコンパイラ (gc)

Go言語の公式コンパイラは、通常 gc と呼ばれます。これは、Goソースコードを機械語に変換する役割を担っています。Goのツールチェインの一部として提供され、go build コマンドなどで内部的に利用されます。

GOEXPERIMENT 環境変数

GOEXPERIMENT は、Go言語のツールチェイン(コンパイラ、リンカなど)の実験的な機能を有効にするために使用される環境変数です。Goの開発チームは、新しい機能や大きな変更を導入する前に、この環境変数を使ってそれらをテストし、フィードバックを収集することがあります。GOEXPERIMENT で有効にされた機能は、安定版のGoリリースには含まれない可能性があり、将来的に変更されたり削除されたりすることがあります。このコミットのケースのように、一時的な互換性レイヤーを提供するためにも使用されることがあります。

パッケージのインポートパス

Go言語では、他のパッケージの機能を利用するために import ステートメントを使用します。import "path/to/package" のように、パッケージのインポートパスを指定します。このパスは、Goのワークスペース内のパッケージの場所や、Goモジュールにおけるパッケージの識別子に対応します。Goの標準ライブラリのパッケージも、fmtnet/http のように特定のインポートパスを持っています。

Strlit 構造体

Goコンパイラの内部で使用される文字列リテラルを表す構造体です。コンパイラがソースコードを解析する際に、文字列定数や識別子などをこの形式で扱います。

技術的詳細

このコミットは、Goコンパイラ (src/cmd/gc/go.hsrc/cmd/gc/lex.c) から GOEXPERIMENT=reorg に関連するコードを削除しています。

具体的には、以下の要素が削除されています。

  1. reorg グローバル変数: src/cmd/gc/go.h から EXTERN int reorg; の宣言が削除されています。これは、GOEXPERIMENT=reorg が有効かどうかを判断するためのフラグでした。
  2. exper 配列からの reorg エントリの削除: src/cmd/gc/lex.c 内の exper 配列は、GOEXPERIMENT 環境変数で制御される実験的なフラグを定義しています。ここから {"reorg", &reorg}, のエントリが削除され、GOEXPERIMENT=reorg を介して reorg フラグを制御するメカニズムがなくなりました。
  3. reorgpath 関数の削除: src/cmd/gc/lex.c から reorgpath 関数とそのプロトタイプ宣言が削除されています。この関数は、古いパッケージパスを新しいパッケージパスに変換するロジックをカプセル化していました。
  4. importfile 関数内の reorg 関連ロジックの削除: src/cmd/gc/lex.cimportfile 関数は、Goソースコード内の import ステートメントを処理する部分です。以前は、reorg フラグが有効な場合に reorgpath 関数を呼び出してインポートパスを変換していましたが、この条件分岐と関数呼び出しが削除されました。
  5. reorgtab テーブルの削除: src/cmd/gc/lex.c から reorgtab という静的な構造体配列が削除されています。このテーブルは、古いパッケージパスと新しいパッケージパスのマッピングを定義していました。例えば、{"json", "encoding/json"} のようなエントリが含まれていました。

これらの変更により、Goコンパイラは GOEXPERIMENT=reorg の機能を持たなくなり、インポートパスの自動変換は行われなくなります。これは、Go言語の標準ライブラリのパッケージ構造が安定し、開発者が手動でインポートパスを更新することが期待されるようになったことを意味します。

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

diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 266cc8597d..faae7bd9ea 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -852,7 +852,6 @@ EXTERN	int	typecheckok;
 EXTERN	int	compiling_runtime;
 
 EXTERN	int	rune32;
-EXTERN	int	reorg;
 
 /*
  *	y.tab.c
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index a07232d1bd..b1eab441c3 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -18,8 +18,6 @@ int windows;
 int yyprev;
 int yylast;
 
-Strlit *reorgpath(Strlit*);
-
 static void	lexinit(void);
 static void	lexinit1(void);
 static void	lexfini(void);
@@ -40,7 +38,6 @@ static struct {
  int *val;
 } exper[] = {
  {"rune32", &rune32},
- {"reorg", &reorg},
 };
 
 static void
@@ -540,9 +537,6 @@ importfile(Val *f, int line)
  		yyerror("import path contains NUL");
  		errorexit();
  	}
-	
-	if(reorg)
-		f->u.sval = reorgpath(f->u.sval);
  
  	// The package name main is no longer reserved,
  	// but we reserve the import path "main" to identify
@@ -2121,47 +2115,3 @@ mkpackage(char* pkgname)
  		outfile = smprint("%s.%c", namebuf, thechar);
  	}
 }
-
-static struct {
-	char *old;
-	char *xnew;
-} reorgtab[] = {
-	{"asn1", "encoding/asn1"},
-	{"big", "math/big"},
-	{"cmath", "math/cmplx"},
-	{"csv", "encoding/csv"},
-	{"exec", "os/exec"},
-	{"exp/template/html", "html/template"},
-	{"gob", "encoding/gob"},
-	{"http", "net/http"},
-	{"http/cgi", "net/http/cgi"},
-	{"http/fcgi", "net/http/fcgi"},
-	{"http/httptest", "net/http/httptest"},
-	{"http/pprof", "net/http/pprof"},
-	{"json", "encoding/json"},
-	{"mail", "net/mail"},
-	{"rpc", "net/rpc"},
-	{"rpc/jsonrpc", "net/rpc/jsonrpc"},
-	{"scanner", "text/scanner"},
-	{"smtp", "net/smtp"},
-	{"syslog", "log/syslog"},
-	{"tabwriter", "text/tabwriter"},
-	{"template", "text/template"},
-	{"template/parse", "text/template/parse"},
-	{"rand", "math/rand"},
-	{"url", "net/url"},
-	{"utf16", "unicode/utf16"},
-	{"utf8", "unicode/utf8"},
-	{"xml", "encoding/xml"},
-};
-
-Strlit*
-reorgpath(Strlit *s)
-{
-	int i;
-
-	for(i=0; i < nelem(reorgtab); i++)
-		if(strcmp(s->s, reorgtab[i].old) == 0)
-			return strlit(reorgtab[i].xnew);
-	return s;
-}

コアとなるコードの解説

src/cmd/gc/go.h

  • -EXTERN int reorg;
    • reorg という名前のグローバル変数の宣言が削除されています。この変数は、GOEXPERIMENT=reorg が有効であるかどうかを示すフラグとして使用されていました。この行の削除により、コンパイラの他の部分から reorg フラグを参照する手段がなくなります。

src/cmd/gc/lex.c

  • -Strlit *reorgpath(Strlit*);
    • reorgpath 関数の前方宣言が削除されています。これは、この関数自体が削除されるため、不要になったものです。
  • exper 配列の変更:
    - {"reorg", &reorg},
    
    • exper 配列は、GOEXPERIMENT 環境変数によって制御される実験的なフラグとその対応するグローバル変数をマッピングしています。ここから {"reorg", &reorg} のエントリが削除されたことで、GOEXPERIMENT=reorg を設定しても reorg 変数が有効になることはなくなりました。
  • importfile 関数の変更:
    -	if(reorg)
    -		f->u.sval = reorgpath(f->u.sval);
    
    • importfile 関数は、Goソースコード内の import パスを処理する部分です。以前は、reorg フラグが有効な場合にのみ、reorgpath 関数を呼び出してインポートパスを変換していました。この条件分岐と reorgpath の呼び出しが削除されたことで、インポートパスの自動変換ロジックが完全に削除されました。
  • reorgtab テーブルと reorgpath 関数の削除:
    -static struct {
    -	char *old;
    -	char *xnew;
    -} reorgtab[] = {
    -	{"asn1", "encoding/asn1"},
    -	// ... (他のエントリ)
    -};
    -
    -Strlit*
    -reorgpath(Strlit *s)
    -{
    -	int i;
    -
    -	for(i=0; i < nelem(reorgtab); i++)
    -		if(strcmp(s->s, reorgtab[i].old) == 0)
    -			return strlit(reorgtab[i].xnew);
    -	return s;
    -}
    
    • reorgtab は、古いパッケージパス(old)と新しいパッケージパス(xnew)の対応関係を定義する静的なテーブルでした。
    • reorgpath 関数は、この reorgtab を参照して、与えられた Strlit 型のインポートパス sreorgtab 内の old パスと一致する場合、対応する xnew パスに変換して返す役割を担っていました。
    • これらのコードブロック全体が削除されたことで、パッケージパスの自動変換機能の実装が完全にコンパイラから取り除かれました。

これらの変更は、GOEXPERIMENT=reorg が提供していた一時的な互換性レイヤーが不要になったことを明確に示しています。

関連リンク

  • 元の変更リスト (CL 5375043): https://golang.org/cl/5375043
  • このコミットの変更リスト (CL 5370043): https://golang.org/cl/5370043

参考にした情報源リンク

  • Go言語の公式ドキュメント (パッケージのインポートパス、go build など): https://go.dev/doc/
  • Go言語の実験的な機能に関する情報 (GOEXPERIMENT): https://go.dev/doc/go1.18#goexperiment (これはGo 1.18のドキュメントですが、GOEXPERIMENT の概念を理解するのに役立ちます)
  • Go言語のコンパイラ (gc) の内部構造に関する情報 (Goのソースコードリポジトリや関連するブログ記事など)
  • Go言語のパッケージ再編成に関する議論やアナウンス (Goのメーリングリストやブログなど)