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

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

このコミットは、Go言語のテストスイート内の test/fixedbugs/bug388.go ファイルに対する変更を記録しています。具体的には、runtime.UintType がGoのランタイムから削除されたことに伴い、gccgo コンパイラが生成するエラーメッセージの期待値が更新されています。これは、Go言語の進化に伴うコンパイラの挙動の変化に適応するためのメンテナンスコミットです。

コミット

commit 06b7024462a5fb6cd43909eb37cefbef04fb9171
Author: Ian Lance Taylor <iant@golang.org>
Date:   Mon Mar 5 16:21:46 2012 -0800

    test: match gccgo error messages for bug388.go
    
    As runtime.UintType is no longer defined, the gccgo error
    messages have changed.
    
    bug388.go:12:10: error: reference to undefined identifier ‘runtime.UintType’
    bug388.go:12:10: error: invalid named/anonymous mix
    bug388.go:13:21: error: reference to undefined identifier ‘runtime.UintType’
    bug388.go:17:10: error: reference to undefined identifier ‘runtime.UintType’
    bug388.go:18:18: error: reference to undefined identifier ‘runtime.UintType’
    bug388.go:22:9: error: non-name on left side of ‘:=’
    bug388.go:27:10: error: expected type
    bug388.go:32:9: error: expected type
    bug388.go:23:14: error: reference to field ‘i’ in object which has no fields or methods
    
    R=golang-dev, gri
    CC=golang-dev
    https://golang.org/cl/5755044

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

https://github.com/golang/go/commit/06b7024462a5fb6cd43909eb37cefbef04fb9171

元コミット内容

このコミットの目的は、test/fixedbugs/bug388.go というテストファイルにおいて、gccgo コンパイラが生成するエラーメッセージの期待値を更新することです。これは、Go言語のランタイムライブラリから runtime.UintType が削除されたため、この型を参照するコードがもはや有効ではなくなり、gccgo が新しいエラーメッセージを出力するようになったことに対応しています。コミットメッセージには、gccgo が出力する具体的なエラーメッセージの例が列挙されており、これらがテストで期待される新しいエラーとして追加されることを示唆しています。

変更の背景

この変更の背景には、Go言語の進化と、そのランタイムライブラリの設計変更があります。初期のGo言語には、runtime パッケージ内に UintType のような、Goのプリミティブ型を表現するための内部的な型が存在していた可能性があります。しかし、Go言語が成熟し、型システムが安定するにつれて、このような内部的な型は不要になったり、より適切な抽象化に置き換えられたりすることがあります。

runtime.UintType が「もはや定義されていない」とコミットメッセージに明記されていることから、この型がGoの標準ライブラリから削除されたか、あるいはその定義が変更されたことが推測されます。これにより、bug388.go のような、意図的に不正なコードを記述してコンパイラのエラーハンドリングをテストするファイルでは、期待されるエラーメッセージが変化します。

特に、gccgo はGo言語の代替コンパイラであり、GCC(GNU Compiler Collection)のフロントエンドとしてGoコードをコンパイルします。標準のGoコンパイラ(gc)とは異なる実装であるため、同じ不正なコードに対しても、異なる、あるいはより詳細なエラーメッセージを生成することがあります。runtime.UintType の削除は、gcgccgo の両方に影響を与えますが、このコミットは特に gccgo のエラーメッセージの変更に焦点を当てています。これは、Goプロジェクトが複数のコンパイラ実装(gcgccgo)をサポートし、それぞれのコンパイラが期待通りにエラーを報告することを確認していることを示しています。

前提知識の解説

Go言語の型システムと runtime パッケージ

Go言語は静的型付け言語であり、変数は使用前に型を宣言する必要があります。Goの型システムはシンプルでありながら強力で、プリミティブ型(int, string, bool など)、複合型(struct, array, slice, map など)、インターフェース型などがあります。

runtime パッケージは、Goプログラムのランタイムシステムと対話するための低レベルな機能を提供します。これには、ガベージコレクション、ゴルーチン管理、プロファイリング、OSとのインタラクションなどが含まれます。通常、アプリケーション開発者が runtime パッケージの内部的な型や関数を直接使用することは稀であり、主にGo言語のコア開発者や、非常に低レベルなシステムプログラミングを行う場合に利用されます。runtime.UintType のような型は、Goコンパイラやランタイムの内部実装で使用されていた可能性が高いです。

gccgogc コンパイラ

Go言語には主に二つの主要なコンパイラ実装が存在します。

  1. gc (Go Compiler): これはGoプロジェクトによって公式に開発・メンテナンスされている標準のコンパイラです。Go言語のリリースサイクルに合わせて進化し、Goの最新の機能と最適化をサポートします。ほとんどのGo開発者はこのコンパイラを使用します。
  2. gccgo: これはGCC(GNU Compiler Collection)の一部として開発されているGoコンパイラです。gccgo は、GoコードをGCCのバックエンドを通じてコンパイルするため、C/C++などの他の言語と同じ最適化パスやターゲットアーキテクチャのサポートを利用できます。gccgogc とは独立して開発されており、Go言語の仕様に準拠していますが、エラーメッセージの形式や、特定のコーナーケースでの挙動が gc と異なることがあります。

テストにおけるエラーメッセージの検証

ソフトウェア開発において、コンパイラやリンカが不正なコードに対して適切なエラーメッセージを生成することは非常に重要です。これにより、開発者は問題の原因を迅速に特定し、修正することができます。Go言語のテストスイートには、意図的に不正なコードを含むテストファイル(fixedbugs ディレクトリなど)が含まれており、これらのファイルはコンパイラが特定のエラーメッセージを生成することを期待しています。

テストファイル内のコメントに // ERROR "..."// GCCGO_ERROR "..." のようなディレクティブが含まれている場合、これはその行でコンパイラが特定のパターンに一致するエラーメッセージを出力することを期待していることを示します。このコミットでは、gccgo のエラーメッセージが変更されたため、これらの期待値を更新する必要がありました。

技術的詳細

このコミットの技術的詳細は、主にGoコンパイラ(特にgccgo)のエラー報告メカニズムと、テストフレームワークにおけるエラーメッセージのパターンマッチングにあります。

runtime.UintType がGoのランタイムから削除された結果、この型を参照するコードはもはや有効なGoコードではありません。Goコンパイラは、未定義の識別子や無効な型参照に対してエラーを報告する必要があります。gccgo は、この変更を受けて、以前とは異なる、より具体的なエラーメッセージを生成するようになりました。

コミットメッセージに示されているエラーメッセージの例は、gccgo がどのようにエラーを報告するかを示しています。

  • reference to undefined identifier ‘runtime.UintType’: これは、runtime.UintType がスコープ内に存在しない、または定義されていないことを明確に示しています。
  • invalid named/anonymous mix: これは、関数の引数リストなどで、名前付きパラメータと匿名パラメータの混在が不正であることを示唆しています。runtime.UintType が型として使用されている文脈で、これがパラメータ名と誤解されたか、あるいは型と名前の組み合わせが不正であると判断された可能性があります。
  • non-name on left side of ‘:=’: これは、:= 演算子(短い変数宣言)の左辺に変数名ではないものが来ていることを示しています。runtime.UintType := i のようなコードは、runtime.UintType が型であり、変数名ではないため、このエラーが発生します。
  • reference to field ‘i’ in object which has no fields or methods: これは、存在しないフィールドへのアクセスを試みた場合に発生します。bug388.go の特定の行で、runtime.UintType が構造体のように扱われ、そのフィールドにアクセスしようとしたが、実際にはフィールドを持たないため、このエラーが発生したと考えられます。

これらのエラーメッセージは、gccgo がGo言語の仕様に厳密に従い、不正なコードに対して正確な診断を提供していることを示しています。テストファイル bug388.go は、これらのエラーが期待通りに発生することを確認するためのものです。コミットで行われた変更は、テストファイル内のコメントに記述された期待されるエラーメッセージのパターンを、gccgo が実際に生成する新しいメッセージに合わせて更新することです。これにより、gccgo でテストを実行した際に、テストが正しくパスするようになります。

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

変更は test/fixedbugs/bug388.go ファイルのみです。

--- a/test/fixedbugs/bug388.go
+++ b/test/fixedbugs/bug388.go
@@ -9,13 +9,13 @@
 package main
 import "runtime"
 
-func foo(runtime.UintType, i int) {  // ERROR "cannot declare name runtime.UintType|named/anonymous mix"
-	println(i, runtime.UintType) 
+func foo(runtime.UintType, i int) {  // ERROR "cannot declare name runtime.UintType|named/anonymous mix|undefined identifier"
+	println(i, runtime.UintType) // GCCGO_ERROR "undefined identifier"
 }
 
 func bar(i int) {
-\truntime.UintType := i       // ERROR "cannot declare name runtime.UintType|non-name on left side"
-\tprintln(runtime.UintType)\t// GCCGO_ERROR "invalid use of type"\n
+\truntime.UintType := i       // ERROR "cannot declare name runtime.UintType|non-name on left side|undefined identifier"
+\tprintln(runtime.UintType)\t// GCCGO_ERROR "invalid use of type|undefined identifier"\n
 }
 
 func baz() {

コアとなるコードの解説

このコミットにおけるコードの変更は、Goのテストファイル bug388.go 内のコメント行に限定されています。これらのコメントは、特定の行でコンパイラがどのようなエラーメッセージを生成することを期待するかを示す「エラーディレクティブ」です。

  • // ERROR "...": これは、Goの標準コンパイラ (gc) が出力するエラーメッセージのパターンを期待するものです。
  • // GCCGO_ERROR "...": これは、gccgo コンパイラが特定の行で出力するエラーメッセージのパターンを期待するものです。

変更点を見ていきましょう。

  1. func foo(runtime.UintType, i int) の行 (+func foo(runtime.UintType, i int) { // ERROR "cannot declare name runtime.UintType|named/anonymous mix|undefined identifier"):

    • 元の行では、gccannot declare name runtime.UintType または named/anonymous mix のエラーを出すことを期待していました。
    • 変更後、|undefined identifier が追加されました。これは、gcruntime.UintType が未定義であることを報告するようになったことを示唆しています。
  2. println(i, runtime.UintType) の行 (+println(i, runtime.UintType) // GCCGO_ERROR "undefined identifier"):

    • この行は元々 GCCGO_ERROR ディレクティブを持っていませんでした。
    • 変更後、// GCCGO_ERROR "undefined identifier" が追加されました。これは、gccgo がこの行で runtime.UintType が未定義であるというエラーを出すことを明示的に期待するようになったことを意味します。
  3. runtime.UintType := i の行 (+runtime.UintType := i // ERROR "cannot declare name runtime.UintType|non-name on left side|undefined identifier"):

    • 元の行では、gccannot declare name runtime.UintType または non-name on left side のエラーを出すことを期待していました。
    • 変更後、|undefined identifier が追加されました。これも、gc が未定義の識別子エラーを報告するようになったことを示しています。
  4. println(runtime.UintType) の行 (+println(runtime.UintType) // GCCGO_ERROR "invalid use of type|undefined identifier"):

    • 元の行では、gccgoinvalid use of type のエラーを出すことを期待していました。
    • 変更後、|undefined identifier が追加されました。これは、gccgoinvalid use of type に加えて、undefined identifier のエラーも出すようになったことを示しています。

これらの変更は、runtime.UintType の削除というGo言語の内部的な変更が、gcgccgo の両方のコンパイラのエラー報告に影響を与えたことを反映しています。テストファイルは、これらのコンパイラが期待されるエラーを正確に報告することを確認するための「契約」のような役割を果たしており、コンパイラの挙動が変化した際には、この契約も更新される必要があります。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • GCCGoのドキュメント
  • Go言語のソースコードとコミット履歴
  • Go言語のメーリングリストやフォーラム(golang-dev など)