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

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

このコミットは、Go言語のコンパイラ(gc)において、インポートパスにチルダ(~)文字の使用を許可するように変更を加えるものです。これにより、Windows環境における特定のパス形式や、Goパーサーの既存の挙動との整合性が改善され、ビルドの問題が修正されます。

コミット

commit d0a4c9bb626df78230613162b0dc07c72855b3c1
Author: Rob Pike <r@golang.org>
Date:   Tue Mar 13 16:03:19 2012 +1100

    gc: allow ~ in import paths
    Windows has paths like C:/Users/ADMIN~1. Also, it so happens
    that go/parser allows ~ in import paths. So does the spec.
    Fixes the build too.
    
    R=golang-dev, dsymonds
    CC=golang-dev
    https://golang.org/cl/5777073

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

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

元コミット内容

gc: allow ~ in import paths
Windows has paths like C:/Users/ADMIN~1. Also, it so happens
that go/parser allows ~ in import paths. So does the spec.
Fixes the build too.

変更の背景

この変更の背景には、主に以下の2つの要因があります。

  1. Windowsにおけるパスの特殊性: Windowsオペレーティングシステムでは、ファイルシステムが短いファイル名(8.3形式)をサポートしており、長いファイル名が切り詰められる際にチルダ(~)と数字が組み合わされた形式(例: ADMIN~1)が生成されることがあります。GoのインポートパスがこのようなWindows特有のパスを含む場合、コンパイラがこれを不正な文字として扱ってしまうと、ビルドエラーが発生する可能性がありました。
  2. Go言語の仕様とパーサーの挙動との不一致: Go言語の仕様(Go Language Specification)では、インポートパスに使用できる文字について特定のルールが定められています。また、go/parserパッケージはGoのソースコードを解析する際に、インポートパスにチルダ文字が含まれていても許容する挙動を示していました。しかし、コンパイラ(gc)の内部処理では、チルダ文字が不正な文字として扱われており、この間に不一致が生じていました。この不一致が、Windows環境でのビルド問題を引き起こす一因となっていました。

このコミットは、これらの不一致を解消し、GoコンパイラがWindowsのパス形式やGo言語の仕様、そしてgo/parserの挙動と整合性を持つようにすることで、Goプログラムのクロスプラットフォーム互換性とビルドの信頼性を向上させることを目的としています。

前提知識の解説

このコミットを理解するためには、以下の前提知識が役立ちます。

  • Go言語のインポートパス: Go言語では、パッケージをインポートする際に、そのパッケージのパスを指定します。このパスは通常、Goモジュールのルートからの相対パスや、標準ライブラリのパッケージ名などです。例えば、import "fmt"import "github.com/user/repo/pkg" のように記述されます。インポートパスは、Goツールチェーンがソースファイルを特定し、依存関係を解決するために非常に重要です。
  • Goコンパイラ (gc): gcはGo言語の公式コンパイラであり、Goのソースコードを機械語に変換する役割を担っています。コンパイルプロセス中には、インポートパスの解析や検証も行われます。
  • go/parserパッケージ: Goの標準ライブラリの一部であるgo/parserパッケージは、Goのソースコードを解析し、抽象構文木(AST)を生成するために使用されます。このパッケージは、Goのツール(goimportsgofmtなど)やIDE、リンターなどで広く利用されています。
  • Windowsのファイルパスと8.3形式: Windowsのファイルシステム(特にFAT32やNTFSの一部互換モード)では、長いファイル名に対して短いファイル名(8.3形式、例: PROGRA~1 for Program Files)が自動的に生成されることがあります。これは、古いDOSアプリケーションとの互換性を保つために導入されたもので、パス中にチルダ(~)と数字が含まれる特徴があります。
  • utfrune関数: このコミットで変更されているutfrune関数は、Goの内部で文字列(UTF-8エンコードされた文字列)の中から特定のルーン(Unicodeコードポイント)を探すために使用される関数です。C言語のstrchrwcschrに似ていますが、UTF-8文字列を適切に扱います。

技術的詳細

このコミットの技術的な核心は、Goコンパイラのインポートパス検証ロジックの変更にあります。具体的には、src/cmd/gc/subr.cファイル内のisbadimport関数が修正されています。

isbadimport関数は、与えられたインポートパスがGoの規則に違反していないかをチェックする役割を担っています。この関数は、インポートパスに含まれる各文字を走査し、不正な文字が含まれていないかを確認します。

変更前は、この関数内でインポートパスに含めることができない文字のリストにチルダ(~)が含まれていました。これは、Goのインポートパスが通常、URLのような形式で表現され、特殊文字の使用が制限されるという一般的な慣習に基づいていた可能性があります。

しかし、前述の通り、Windowsのファイルシステムではチルダを含むパスが合法的に存在し、またGo言語の仕様やgo/parserの挙動がチルダを許容していたため、コンパイラ側でのこの制限は不整合を引き起こしていました。

このコミットでは、isbadimport関数内の不正文字リストからチルダ(~)が削除されました。これにより、コンパイラはインポートパスにチルダが含まれていても、それを不正な文字としてフラグ付けしなくなり、Windows環境でのビルド問題が解消されます。

この変更は、Go言語のクロスプラットフォーム互換性を高める上で重要です。特に、WindowsユーザーがGoのソースコードをビルドする際に、ファイルパスの差異によって予期せぬエラーに遭遇するのを防ぎます。また、Go言語の異なるコンポーネント(コンパイラとパーサー)間での挙動の整合性を保つことにも寄与しています。

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

変更はsrc/cmd/gc/subr.cファイルの一箇所のみです。

--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -3639,7 +3639,7 @@ isbadimport(Strlit *path)
 			yyerror("import path contains space character: \"%s\"", path->s);
 			return 1;
 		}
-		if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}~", r)) {
+		if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}", r)) {
 			yyerror("import path contains invalid character '%C': \"%s\"", r, path->s);
 			return 1;
 		}

コアとなるコードの解説

上記のコードスニペットは、isbadimport関数内の特定の条件分岐を示しています。

  • if(utfrune("!\"#$%&'()*,:;<=>?[]^{|}~", r)) { ... }` (変更前)
  • if(utfrune("!\"#$%&'()*,:;<=>?[]^{|}", r)) { ... }` (変更後)

この行は、インポートパスの各ルーン(r)が、指定された不正文字の集合に含まれているかどうかをチェックしています。utfrune関数は、第一引数で与えられた文字列(この場合は不正文字の集合を表す文字列リテラル)の中に、第二引数で与えられたルーンrが存在するかどうかを調べます。存在すれば真を返し、yyerror関数を呼び出してエラーメッセージを出力し、1を返して不正なインポートパスであることを示します。

変更前は、不正文字の集合を表す文字列リテラルにチルダ(~)が含まれていました。これが、インポートパスにチルダが含まれる場合にエラーとなる原因でした。

変更後、この文字列リテラルからチルダ(~)が削除されています。これにより、utfrune関数がチルダに対して真を返すことがなくなり、インポートパスにチルダが含まれていてもエラーとして扱われなくなりました。

この修正は非常に局所的ですが、Goコンパイラのインポートパス処理における重要な挙動変更であり、Windows環境での互換性問題を解決する上で不可欠な変更でした。

関連リンク

  • Go Language Specification: https://go.dev/ref/spec (特に "Import declarations" のセクション)
  • Go go/parser package documentation: https://pkg.go.dev/go/parser
  • Go CL 5777073 (Gerrit Change-Id): https://golang.org/cl/5777073 (これはコミットメッセージに記載されているGerritの変更リストへのリンクです。GoプロジェクトではGitHubにプッシュされる前にGerritでコードレビューが行われます。)

参考にした情報源リンク

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

このコミットは、Go言語のコンパイラ(gc)において、インポートパスにチルダ(~)文字の使用を許可するように変更を加えるものです。これにより、Windows環境における特定のパス形式や、Goパーサーの既存の挙動との整合性が改善され、ビルドの問題が修正されます。

コミット

commit d0a4c9bb626df78230613162b0dc07c72855b3c1
Author: Rob Pike <r@golang.org>
Date:   Tue Mar 13 16:03:19 2012 +1100

    gc: allow ~ in import paths
    Windows has paths like C:/Users/ADMIN~1. Also, it so happens
    that go/parser allows ~ in import paths. So does the spec.
    Fixes the build too.
    
    R=golang-dev, dsymonds
    CC=golang-dev
    https://golang.org/cl/5777073

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

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

元コミット内容

gc: allow ~ in import paths
Windows has paths like C:/Users/ADMIN~1. Also, it so happens
that go/parser allows ~ in import paths. So does the spec.
Fixes the build too.

変更の背景

この変更の背景には、主に以下の2つの要因があります。

  1. Windowsにおけるパスの特殊性: Windowsオペレーティングシステムでは、ファイルシステムが短いファイル名(8.3形式)をサポートしており、長いファイル名が切り詰められる際にチルダ(~)と数字が組み合わされた形式(例: ADMIN~1)が生成されることがあります。GoのインポートパスがこのようなWindows特有のパスを含む場合、コンパイラがこれを不正な文字として扱ってしまうと、ビルドエラーが発生する可能性がありました。
  2. Go言語の仕様とパーサーの挙動との不一致: Go言語の仕様(Go Language Specification)では、インポートパスに使用できる文字について特定のルールが定められています。また、go/parserパッケージはGoのソースコードを解析する際に、インポートパスにチルダ文字が含まれていても許容する挙動を示していました。しかし、コンパイラ(gc)の内部処理では、チルダ文字が不正な文字として扱われており、この間に不一致が生じていました。この不一致が、Windows環境でのビルド問題を引き起こす一因となっていました。

このコミットは、これらの不一致を解消し、GoコンパイラがWindowsのパス形式やGo言語の仕様、そしてgo/parserの挙動と整合性を持つようにすることで、Goプログラムのクロスプラットフォーム互換性とビルドの信頼性を向上させることを目的としています。

前提知識の解説

このコミットを理解するためには、以下の前提知識が役立ちます。

  • Go言語のインポートパス: Go言語では、パッケージをインポートする際に、そのパッケージのパスを指定します。このパスは通常、Goモジュールのルートからの相対パスや、標準ライブラリのパッケージ名などです。例えば、import "fmt"import "github.com/user/repo/pkg" のように記述されます。インポートパスは、Goツールチェーンがソースファイルを特定し、依存関係を解決するために非常に重要です。
  • Goコンパイラ (gc): gcはGo言語の公式コンパイラであり、Goのソースコードを機械語に変換する役割を担っています。コンパイルプロセス中には、インポートパスの解析や検証も行われます。
  • go/parserパッケージ: Goの標準ライブラリの一部であるgo/parserパッケージは、Goのソースコードを解析し、抽象構文木(AST)を生成するために使用されます。このパッケージは、Goのツール(goimportsgofmtなど)やIDE、リンターなどで広く利用されています。
  • Windowsのファイルパスと8.3形式: Windowsのファイルシステム(特にFAT32やNTFSの一部互換モード)では、長いファイル名に対して短いファイル名(8.3形式、例: PROGRA~1 for Program Files)が自動的に生成されることがあります。これは、古いDOSアプリケーションとの互換性を保つために導入されたもので、パス中にチルダ(~)と数字が含まれる特徴があります。
  • utfrune関数: このコミットで変更されているutfrune関数は、Goの内部で文字列(UTF-8エンコードされた文字列)の中から特定のルーン(Unicodeコードポイント)を探すために使用される関数です。C言語のstrchrwcschrに似ていますが、UTF-8文字列を適切に扱います。

技術的詳細

このコミットの技術的な核心は、Goコンパイラのインポートパス検証ロジックの変更にあります。具体的には、src/cmd/gc/subr.cファイル内のisbadimport関数が修正されています。

isbadimport関数は、与えられたインポートパスがGoの規則に違反していないかをチェックする役割を担っています。この関数は、インポートパスに含まれる各文字を走査し、不正な文字が含まれていないかを確認します。

変更前は、この関数内でインポートパスに含めることができない文字のリストにチルダ(~)が含まれていました。これは、Goのインポートパスが通常、URLのような形式で表現され、特殊文字の使用が制限されるという一般的な慣習に基づいていた可能性があります。

しかし、前述の通り、Windowsのファイルシステムではチルダを含むパスが合法的に存在し、またGo言語の仕様やgo/parserの挙動がチルダを許容していたため、コンパイラ側でのこの制限は不整合を引き起こしていました。

このコミットでは、isbadimport関数内の不正文字リストからチルダ(~)が削除されました。これにより、コンパイラはインポートパスにチルダが含まれていても、それを不正な文字としてフラグ付けしなくなり、Windows環境でのビルド問題が解消されます。

この変更は、Go言語のクロスプラットフォーム互換性を高める上で重要です。特に、WindowsユーザーがGoのソースコードをビルドする際に、ファイルパスの差異によって予期せぬエラーに遭遇するのを防ぎます。また、Go言語の異なるコンポーネント(コンパイラとパーサー)間での挙動の整合性を保つことにも寄与しています。

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

変更はsrc/cmd/gc/subr.cファイルの一箇所のみです。

--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -3639,7 +3639,7 @@ isbadimport(Strlit *path)
 			yyerror("import path contains space character: \"%s\"", path->s);
 			return 1;
 		}
-		if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}~", r)) {
+		if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}", r)) {
 			yyerror("import path contains invalid character '%C': \"%s\"", r, path->s);
 			return 1;
 		}

コアとなるコードの解説

上記のコードスニペットは、isbadimport関数内の特定の条件分岐を示しています。

  • if(utfrune("!\"#$%&'()*,:;<=>?[]^{|}~", r)) { ... }` (変更前)
  • if(utfrune("!\"#$%&'()*,:;<=>?[]^{|}", r)) { ... }` (変更後)

この行は、インポートパスの各ルーン(r)が、指定された不正文字の集合に含まれているかどうかをチェックしています。utfrune関数は、第一引数で与えられた文字列(この場合は不正文字の集合を表す文字列リテラル)の中に、第二引数で与えられたルーンrが存在するかどうかを調べます。存在すれば真を返し、yyerror関数を呼び出してエラーメッセージを出力し、1を返して不正なインポートパスであることを示します。

変更前は、不正文字の集合を表す文字列リテラルにチルダ(~)が含まれていました。これが、インポートパスにチルダが含まれる場合にエラーとなる原因でした。

変更後、この文字列リテラルからチルダ(~)が削除されています。これにより、utfrune関数がチルダに対して真を返すことがなくなり、インポートパスにチルダが含まれていてもエラーとして扱われなくなりました。

この修正は非常に局所的ですが、Goコンパイラのインポートパス処理における重要な挙動変更であり、Windows環境での互換性問題を解決する上で不可欠な変更でした。

関連リンク

  • Go Language Specification: https://go.dev/ref/spec (特に "Import declarations" のセクション)
  • Go go/parser package documentation: https://pkg.go.dev/go/parser
  • Go CL 5777073 (Gerrit Change-Id): https://golang.org/cl/5777073 (これはコミットメッセージに記載されているGerritの変更リストへのリンクです。GoプロジェクトではGitHubにプッシュされる前にGerritでコードレビューが行われます。)

参考にした情報源リンク

  • Windows 8.3 filename: https://en.wikipedia.org/wiki/8.3_filename
  • Go source code (for context on src/cmd/gc/subr.c and utfrune): https://github.com/golang/go
  • General understanding of Go compiler and import paths.
  • Web search results for "Go compiler gc import paths tilde Windows ADMIN~1" (used to confirm the context of Windows 8.3 filenames and their interaction with Go import paths).