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

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

このコミットは、Go言語のテストスイートにおけるエラーメッセージの期待値を更新するものです。具体的には、Goの公式コンパイラであるgcと、GCCベースのGoコンパイラであるgccgoの間で発生するエラーメッセージの差異を吸収し、テストが両方のコンパイラで適切に動作するように調整しています。これにより、Go言語のテストの堅牢性と互換性が向上します。

コミット

commit d5b7c5157efd3b3089213761d8222c0d4dd03ab3
Author: Ian Lance Taylor <iant@golang.org>
Date:   Thu Jan 26 23:06:47 2012 -0800

    test: match gccgo error messages
    
    complit1.go:37:34: error: may only omit types within composite literals of slice, array, or map type
    complit1.go:38:19: error: may only omit types within composite literals of slice, array, or map type
    complit1.go:18:21: error: slice of unaddressable value
    complit1.go:19:10: error: slice of unaddressable value
    complit1.go:20:9: error: slice of unaddressable value
    
    convert1.go:28:13: error: invalid type conversion
    convert1.go:32:12: error: invalid type conversion (cannot use type string as type Tint64)
    convert1.go:36:12: error: invalid type conversion
    convert1.go:37:13: error: invalid type conversion
    convert1.go:40:11: error: invalid type conversion
    convert1.go:41:12: error: invalid type conversion
    convert1.go:44:12: error: invalid type conversion
    convert1.go:46:13: error: invalid type conversion
    convert1.go:48:11: error: invalid type conversion
    convert1.go:50:12: error: invalid type conversion
    convert1.go:52:6: error: invalid type conversion
    convert1.go:53:12: error: invalid type conversion
    convert1.go:54:12: error: invalid type conversion
    convert1.go:56:13: error: invalid type conversion
    convert1.go:57:11: error: invalid type conversion
    convert1.go:58:11: error: invalid type conversion
    convert1.go:64:13: error: invalid type conversion
    convert1.go:68:12: error: invalid type conversion (cannot use type Tstring as type Tint64)
    convert1.go:72:12: error: invalid type conversion
    convert1.go:73:13: error: invalid type conversion
    convert1.go:76:11: error: invalid type conversion (cannot use type Tbyte as type Trune)
    convert1.go:77:12: error: invalid type conversion (cannot use type Tbyte as type Tint64)
    convert1.go:80:12: error: invalid type conversion
    convert1.go:82:13: error: invalid type conversion
    convert1.go:84:11: error: invalid type conversion (cannot use type Trune as type Tbyte)
    convert1.go:86:12: error: invalid type conversion (cannot use type Trune as type Tint64)
    convert1.go:88:6: error: invalid type conversion (cannot use type Tint64 as type string)
    convert1.go:89:12: error: invalid type conversion
    convert1.go:90:12: error: invalid type conversion
    convert1.go:92:13: error: invalid type conversion (cannot use type Tint64 as type Tstring)
    convert1.go:93:11: error: invalid type conversion (cannot use type Tint64 as type Tbyte)
    convert1.go:94:11: error: invalid type conversion (cannot use type Tint64 as type Trune)
    
    fixedbugs/bug195.go:9:21: error: interface contains embedded non-interface
    fixedbugs/bug195.go:12:21: error: interface contains embedded non-interface
    fixedbugs/bug195.go:15:15: error: interface contains embedded non-interface
    fixedbugs/bug195.go:18:2: error: invalid recursive interface
    fixedbugs/bug195.go:26:2: error: invalid recursive interface
    fixedbugs/bug195.go:22:2: error: invalid recursive interface
    
    fixedbugs/bug251.go:15:2: error: invalid recursive interface
    fixedbugs/bug251.go:11:2: error: invalid recursive interface
    
    fixedbugs/bug374.go:18:34: error: use of undefined type ‘xxxx’
    fixedbugs/bug374.go:16:5: error: incompatible type in initialization (incompatible type for method ‘m’ (different number of parameters))
    
    fixedbugs/bug383.go:11:2: error: expected boolean expression
    fixedbugs/bug383.go:12:2: error: expected boolean expression
    
    fixedbugs/bug386.go:10:25: error: incompatible type for return value 1 (type has no methods)
    fixedbugs/bug386.go:12:25: error: incompatible type for return value 1 (type has no methods)
    
    fixedbugs/bug388.go:12:10: error: invalid named/anonymous mix
    fixedbugs/bug388.go:17:19: error: non-name on left side of ‘:=’
    fixedbugs/bug388.go:22:9: error: non-name on left side of ‘:=’
    fixedbugs/bug388.go:27:10: error: expected type
    fixedbugs/bug388.go:32:9: error: expected type
    fixedbugs/bug388.go:23:14: error: reference to field ‘i’ in object which has no fields or methods
    fixedbugs/bug388.go:18:18: error: invalid use of type
    
    fixedbugs/bug389.go:12:5: error: incompatible type in initialization (different parameter types)
    
    fixedbugs/bug390.go:15:24: error: expected integer, floating, or complex type
    
    fixedbugs/bug394.go:10:1: error: expected declaration
    
    fixedbugs/bug397.go:12:2: error: incompatible type for element 2 key in map construction
    
    switch3.go:18:2: error: incompatible types in binary expression
    switch3.go:22:2: error: incompatible types in binary expression
    switch3.go:28:2: error: map can only be compared to nil
    switch3.go:35:2: error: slice can only be compared to nil
    switch3.go:42:2: error: func can only be compared to nil
    
    syntax/else.go:11:9: error: expected ‘if’ or ‘{’
    
    typeswitch2.go:15:2: error: duplicate type in switch
    typeswitch2.go:19:2: error: duplicate type in switch
    typeswitch2.go:26:2: error: duplicate type in switch
    typeswitch2.go:40:9: error: ‘t’ declared and not used
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/5573073

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

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

元コミット内容

このコミットは、Go言語のテストスイートが生成するエラーメッセージを、gccgoコンパイラが生成するエラーメッセージと一致させることを目的としています。Go言語には主に2つの主要なコンパイラ実装があります。一つは公式のgc(Go Compiler)であり、もう一つはGCC(GNU Compiler Collection)をベースにしたgccgoです。これら2つのコンパイラは、同じGoのソースコードに対して、異なるエラーメッセージを生成する場合があります。

このコミット以前は、テストスイートが期待するエラーメッセージは主にgcコンパイラに合わせたものでした。そのため、gccgoでテストを実行すると、エラーメッセージの不一致によりテストが失敗する可能性がありました。このコミットは、そのような不一致を解消し、両方のコンパイラでテストが成功するように、テストファイル内の期待されるエラーメッセージを更新しています。

コミットメッセージには、complit1.goconvert1.go、``fixedbugsディレクトリ内の複数のファイル、switch3.gosyntax/else.gotypeswitch2.goなど、影響を受けるファイルと、それぞれのファイルでgccgo`が生成する具体的なエラーメッセージの例が列挙されています。

変更の背景

Go言語は複数のコンパイラ実装を持つことができ、それぞれが言語仕様に準拠しながらも、内部的な実装やエラー報告の粒度において差異が生じることがあります。特に、gcgccgoは異なるコードベースと設計思想を持つため、同じ不正なコードに対して異なるエラーメッセージを出すことは珍しくありません。

Goのテストスイートは、言語の正確な動作を保証するために非常に重要です。これには、コンパイルエラーが期待通りに報告されることも含まれます。もしテストスイートが特定のコンパイラのエラーメッセージにのみ依存している場合、他のコンパイラでテストを実行した際に、コードの振る舞いは正しくても、エラーメッセージの不一致によってテストが失敗するという「偽陽性」の問題が発生します。

このコミットの背景には、gccgoの進化と、Goエコシステム全体での互換性の確保という目的があります。gccgoがGo言語の重要な実装の一つとして成熟するにつれて、そのエラーメッセージもテストスイートで考慮されるべき対象となりました。これにより、開発者はgcgccgoのどちらを使用しても、一貫したテスト結果を得ることができ、Go言語の移植性と堅牢性が高まります。

前提知識の解説

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

  • gc (Go Compiler): Go言語の公式ツールチェインに含まれる標準コンパイラです。Go言語のソースコードを直接機械語にコンパイルします。Go言語のリリースサイクルと密接に連携しており、最新の言語機能や最適化が迅速に導入されます。
  • gccgo: GCC (GNU Compiler Collection) のフロントエンドとして実装されたGoコンパイラです。GCCの既存の最適化インフラストラクチャやバックエンドを利用してGoコードをコンパイルします。gcとは独立して開発されており、GCCのリリースサイクルに従います。そのため、gcとは異なる最適化や、場合によっては異なるエラーメッセージを生成することがあります。

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

Goのテストスイートでは、特定のコードがコンパイルエラーを引き起こすことを期待する場合、そのエラーメッセージを検証するために特別なコメントを使用します。

  • // ERROR "expected error message": このコメントは、その行またはその近くのコードが、指定されたエラーメッセージを含むコンパイルエラーを生成することを期待することを示します。テスト実行時に、コンパイラがこのエラーメッセージを生成しない場合、または異なるエラーメッセージを生成した場合、テストは失敗します。
  • // GC_ERROR "expected error message": これは、gcコンパイラが特定のエラーメッセージを生成することを期待する場合に使用されていました。
  • // GCCGO_ERROR "expected error message": これは、gccgoコンパイラが特定のエラーメッセージを生成することを期待する場合に使用されます。

| (パイプ) を用いたエラーメッセージの指定

このコミットで頻繁に見られる変更は、// ERROR "message1|message2" の形式です。これは、Goのテストフレームワークにおける特別な構文で、コンパイラがmessage1またはmessage2のいずれかのエラーメッセージを生成した場合に、テストが成功することを示します。この機能は、異なるコンパイラ(gcgccgoなど)が同じ不正なコードに対して、意味的には同じだが表現が異なるエラーメッセージを生成するような場合に非常に有用です。これにより、単一のテストケースで複数のコンパイラの実装を検証できます。

Go言語の構文とセマンティクスに関するエラーの種類

コミットメッセージに記載されているエラーメッセージは、Go言語の様々な構文的・意味的制約に違反した際に発生するものです。

  • 複合リテラル (Composite Literals): &T{0, 0, "", {}} のように、構造体や配列、スライス、マップなどの複合型を初期化する際に使用されます。要素の型を省略できるのは、スライス、配列、マップの複合リテラル内でのみです。
  • 型変換 (Type Conversions): _ = []int64(s) のように、ある型から別の型へ値を変換する操作です。Goの型変換には厳格なルールがあり、互換性のない型間の変換はコンパイルエラーとなります。
  • インターフェースの埋め込み (Interface Embedding): インターフェースが他のインターフェースを埋め込むことで、そのメソッドセットを継承できます。しかし、再帰的な埋め込みや、非インターフェース型を埋め込むことはできません。
  • unsafe.Pointer の演算: unsafeパッケージは、Goの型システムをバイパスして低レベルなメモリ操作を可能にしますが、その使用には厳格な制約があります。特に、unsafe.Pointerに対する算術演算は、ポインタ間の差を計算する場合を除き、許可されていません。
  • if 文の条件式: if文の条件式は必ずブール型でなければなりません。
  • switch 文の比較: switch文では、マップ、スライス、関数型はnilとのみ比較可能です。

技術的詳細

このコミットの技術的詳細は、Go言語のテストフレームワークがどのようにコンパイラのエラーメッセージを検証し、異なるコンパイラ間の差異を吸収するかという点に集約されます。

Goのテストスイートでは、test/ディレクトリ配下に多数のテストファイルが存在します。これらのファイルの中には、意図的に不正なGoコードを含み、コンパイラが特定のエラーメッセージを生成することを期待するものが多くあります。このようなテストケースでは、コードの行末に// ERROR "..."のようなコメントが記述されています。

このコミットが行った変更は、主に以下のパターンに従っています。

  1. 既存の// ERRORコメントへの追加: 多くのケースで、既存の// ERROR "original message"というコメントが// ERROR "original message|new message"という形式に変更されています。これは、gcコンパイラがoriginal messageを生成し、gccgoコンパイラがnew messageを生成する場合に、両方のメッセージを許容するようにテストを更新したことを意味します。これにより、どちらのコンパイラでテストを実行しても、期待されるエラーメッセージが検出され、テストが成功します。
  2. GC_ERRORからERRORへの変更: 一部のファイルでは、// GC_ERROR "..."// ERROR "..."に変更されています。これは、以前はgc固有のエラーメッセージとして扱われていたものが、gccgoでも同じ、または互換性のあるエラーメッセージを生成するようになったため、より一般的なERRORコメントで対応できるようになったことを示唆しています。
  3. GCCGO_ERRORの追加: 特定のケースでは、// GCCGO_ERROR "..."というコメントが追加されています。これは、そのエラーメッセージがgccgoに固有のものであり、gcでは異なる(またはエラーにならない)場合に、gccgoでのみそのエラーメッセージを期待することを示します。

これらの変更は、Go言語のテストインフラストラクチャが、複数のコンパイラ実装の存在を認識し、それらの間の微妙な差異を適切に管理するためのメカニズムを提供していることを示しています。これにより、Go言語の進化と、異なるプラットフォームや環境での互換性を維持するための重要な側面が強化されます。

特に、convert1.goにおける大量の変更は、型変換に関するエラーメッセージがgcgccgoで大きく異なっていたことを示しています。gccgoはより一般的な「invalid type conversion」というメッセージを多用する傾向があるのに対し、gcはより詳細な「cannot convert...」というメッセージを生成することが多いようです。このコミットは、これらの差異を|演算子で吸収することで、テストの安定性を確保しています。

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

このコミットは、Go言語のテストスイート内の複数のファイルにわたる変更を含んでいます。以下に、主要な変更パターンと、その影響を受けるファイルの一部を挙げます。

  1. test/complit1.go:

    --- a/test/complit1.go
    +++ b/test/complit1.go
    @@ -34,6 +34,6 @@ type T struct {
     
     var (
     	_ = &T{0, 0, "", nil}               // ok
    -	_ = &T{i: 0, f: 0, s: "", next: {}} // ERROR "missing type in composite literal"
    -	_ = &T{0, 0, "", {}}                // ERROR "missing type in composite literal"
    +	_ = &T{i: 0, f: 0, s: "", next: {}} // ERROR "missing type in composite literal|omit types within composite literal"
    +	_ = &T{0, 0, "", {}}                // ERROR "missing type in composite literal|omit types within composite literal"
     )
    

    複合リテラルにおける型省略のエラーメッセージに|omit types within composite literalが追加されました。

  2. test/convert1.go: このファイルは、型変換に関する多数のテストケースを含んでおり、ほとんどの// ERRORコメントに|invalid type conversionが追加されています。

    --- a/test/convert1.go
    +++ b/test/convert1.go
    @@ -25,72 +25,72 @@ func main() {
     	_ = string(s)
     	_ = []byte(s)
     	_ = []rune(s)
    -	_ = []int64(s) // ERROR "cannot convert.*\[\]int64"
    +	_ = []int64(s) // ERROR "cannot convert.*\[\]int64|invalid type conversion"
     	_ = Tstring(s)
     	_ = Tbyte(s)
     	_ = Trune(s)
    -	_ = Tint64(s) // ERROR "cannot convert.*Tint64"
    +	_ = Tint64(s) // ERROR "cannot convert.*Tint64|invalid type conversion"
     
     	_ = string(sb)
     	_ = []byte(sb)
    -	_ = []rune(sb)  // ERROR "cannot convert.*\\[\]rune"
    -	_ = []int64(sb) // ERROR "cannot convert.*\\[\]int64"
    +	_ = []rune(sb)  // ERROR "cannot convert.*\\[\]rune|invalid type conversion"
    +	_ = []int64(sb) // ERROR "cannot convert.*\\[\]int64|invalid type conversion"
     	_ = Tstring(sb)
     	_ = Tbyte(sb)
    -	_ = Trune(sb)  // ERROR "cannot convert.*Trune"
    -	_ = Tint64(sb) // ERROR "cannot convert.*Tint64"
    +	_ = Trune(sb)  // ERROR "cannot convert.*Trune|invalid type conversion"
    +	_ = Tint64(sb) // ERROR "cannot convert.*Tint64|invalid type conversion"
     
     	_ = string(sr)
    -	_ = []byte(sr) // ERROR "cannot convert.*\\[\]byte"
    +	_ = []byte(sr) // ERROR "cannot convert.*\\[\]byte|invalid type conversion"
     	_ = []rune(sr)
    -	_ = []int64(sr) // ERROR "cannot convert.*\\[\]int64"
    +	_ = []int64(sr) // ERROR "cannot convert.*\\[\]int64|invalid type conversion"
     	_ = Tstring(sr)
    -	_ = Tbyte(sr) // ERROR "cannot convert.*Tbyte"
    +	_ = Tbyte(sr) // ERROR "cannot convert.*Tbyte|invalid type conversion"
     	_ = Trune(sr)
    -	_ = Tint64(sr) // ERROR "cannot convert.*Tint64"
    +	_ = Tint64(sr) // ERROR "cannot convert.*Tint64|invalid type conversion"
     
    -	_ = string(si) // ERROR "cannot convert.* string"
    -	_ = []byte(si) // ERROR "cannot convert.*\\[\]byte"
    -	_ = []rune(si) // ERROR "cannot convert.*\\[\]rune"
    +	_ = string(si) // ERROR "cannot convert.* string|invalid type conversion"
    +	_ = []byte(si) // ERROR "cannot convert.*\\[\]byte|invalid type conversion"
    +	_ = []rune(si) // ERROR "cannot convert.*\\[\]rune|invalid type conversion"
     	_ = []int64(si)
    -	_ = Tstring(si) // ERROR "cannot convert.*Tstring"
    -	_ = Tbyte(si)   // ERROR "cannot convert.*Tbyte"
    -	_ = Trune(si)   // ERROR "cannot convert.*Trune"
    +	_ = Tstring(si) // ERROR "cannot convert.*Tstring|invalid type conversion"
    +	_ = Tbyte(si)   // ERROR "cannot convert.*Tbyte|invalid type conversion"
    +	_ = Trune(si)   // ERROR "cannot convert.*Trune|invalid type conversion"
     	_ = Tint64(si)
     
     	_ = string(ts)
     	_ = []byte(ts)
     	_ = []rune(ts)
    -	_ = []int64(ts) // ERROR "cannot convert.*\\[\]int64"
    +	_ = []int64(ts) // ERROR "cannot convert.*\\[\]int64|invalid type conversion"
     	_ = Tstring(ts)
     	_ = Tbyte(ts)
     	_ = Trune(ts)
    -	_ = Tint64(ts) // ERROR "cannot convert.*Tint64"
    +	_ = Tint64(ts) // ERROR "cannot convert.*Tint64|invalid type conversion"
     
     	_ = string(tsb)
     	_ = []byte(tsb)
    -	_ = []rune(tsb)  // ERROR "cannot convert.*\\[\]rune"
    -	_ = []int64(tsb) // ERROR "cannot convert.*\\[\]int64"
    +	_ = []rune(tsb)  // ERROR "cannot convert.*\\[\]rune|invalid type conversion"
    +	_ = []int64(tsb) // ERROR "cannot convert.*\\[\]int64|invalid type conversion"
     	_ = Tstring(tsb)
     	_ = Tbyte(tsb)
    -	_ = Trune(tsb)  // ERROR "cannot convert.*Trune"
    -	_ = Tint64(tsb) // ERROR "cannot convert.*Tint64"
    +	_ = Trune(tsb)  // ERROR "cannot convert.*Trune|invalid type conversion"
    +	_ = Tint64(tsb) // ERROR "cannot convert.*Tint64|invalid type conversion"
     
     	_ = string(tsr)
    -	_ = []byte(tsr) // ERROR "cannot convert.*\\[\]byte"
    +	_ = []byte(tsr) // ERROR "cannot convert.*\\[\]byte|invalid type conversion"
     	_ = []rune(tsr)
    -	_ = []int64(tsr) // ERROR "cannot convert.*\\[\]int64"
    +	_ = []int64(tsr) // ERROR "cannot convert.*\\[\]int64|invalid type conversion"
     	_ = Tstring(tsr)
    -	_ = Tbyte(tsr) // ERROR "cannot convert.*Tbyte"
    +	_ = Tbyte(tsr) // ERROR "cannot convert.*Tbyte|invalid type conversion"
     	_ = Trune(tsr)
    -	_ = Tint64(tsr) // ERROR "cannot convert.*Tint64"
    +	_ = Tint64(tsr) // ERROR "cannot convert.*Tint64|invalid type conversion"
     
    -	_ = string(tsi) // ERROR "cannot convert.* string"
    -	_ = []byte(tsi) // ERROR "cannot convert.*\\[\]byte"
    -	_ = []rune(tsi) // ERROR "cannot convert.*\\[\]rune"
    +	_ = string(tsi) // ERROR "cannot convert.* string|invalid type conversion"
    +	_ = []byte(tsi) // ERROR "cannot convert.*\\[\]byte|invalid type conversion"
    +	_ = []rune(tsi) // ERROR "cannot convert.*\\[\]rune|invalid type conversion"
     	_ = []int64(tsi)
    -	_ = Tstring(tsi) // ERROR "cannot convert.*Tstring"
    -	_ = Tbyte(tsi)   // ERROR "cannot convert.*Tbyte"
    -	_ = Trune(tsi)   // ERROR "cannot convert.*Trune"
    +	_ = Tstring(tsi) // ERROR "cannot convert.*Tstring|invalid type conversion"
    +	_ = Tbyte(tsi)   // ERROR "cannot convert.*Tbyte|invalid type conversion"
    +	_ = Trune(tsi)   // ERROR "cannot convert.*Trune|invalid type conversion"
     	_ = Tint64(tsi)
     }
    

    この変更は、gccgoが型変換エラーに対してより一般的なメッセージを生成する傾向があることを反映しています。

  3. test/fixedbugs/bug195.go および test/fixedbugs/bug251.go: GC_ERRORERRORに統一されています。

    --- a/test/fixedbugs/bug195.go
    +++ b/test/fixedbugs/bug195.go
    @@ -23,5 +23,5 @@ type I5 interface {
     }
     
     type I6 interface {
    -	I5	// GC_ERROR "interface"
    +	I5	// ERROR "interface"
     }
    
  4. test/fixedbugs/bug374.go: GCCGO_ERRORが追加されています。

    --- a/test/fixedbugs/bug374.go
    +++ b/test/fixedbugs/bug374.go
    @@ -13,8 +13,8 @@ type I interface {
     
     type T int
     
    -var _ I = T(0)
    +var _ I = T(0)	// GCCGO_ERROR "incompatible"
     
     func (T) m(buf []byte) (a int, b xxxx) {  // ERROR "xxxx"
     	return 0, nil
     }
    
  5. test/fixedbugs/bug388.go: 複数のエラーメッセージに|が追加され、GCCGO_ERRORも追加されています。

    --- a/test/fixedbugs/bug388.go
    +++ b/test/fixedbugs/bug388.go
    @@ -9,27 +9,27 @@
     package main
     import "runtime"
     
    -func foo(runtime.UintType, i int) {  // ERROR "cannot declare name runtime.UintType"
    +func foo(runtime.UintType, i int) {  // ERROR "cannot declare name runtime.UintType|named/anonymous mix"
     	println(i, runtime.UintType) 
     }
     
     func bar(i int) {
    -	runtime.UintType := i       // ERROR "cannot declare name runtime.UintType"
    -	println(runtime.UintType)
    +	runtime.UintType := i       // ERROR "cannot declare name runtime.UintType|non-name on left side"
    +	println(runtime.UintType)	// GCCGO_ERROR "invalid use of type"
     }
     
     func baz() {
    -	main.i := 1	// ERROR "non-name main.i"
    -	println(main.i)
    +	main.i := 1	// ERROR "non-name main.i|non-name on left side"
    +	println(main.i)\t// GCCGO_ERROR "no fields or methods"
     }
     
     func qux() {
    -	var main.i	// ERROR "unexpected [.]"
    +	var main.i	// ERROR "unexpected [.]|expected type"
      println(main.i)
     }
     
     func corge() {
    -	var foo.i int  // ERROR "unexpected [.]"
    +	var foo.i int  // ERROR "unexpected [.]|expected type"
      println(foo.i)
     }
    

これらの変更は、Go言語のテストスイートが、異なるコンパイラ実装(特にgcgccgo)間で発生するエラーメッセージの差異を適切に処理し、テストの堅牢性と互換性を高めるためのものです。

コアとなるコードの解説

このコミットにおける「コアとなるコードの変更」は、Go言語のテストファイル内のコメント行です。Goのテストフレームワークは、特定のコンパイルエラーを期待するテストケースにおいて、ソースコードの該当行に特別なコメントを記述することで、そのエラーメッセージを検証します。

変更の核心は、// ERROR "message1" という形式のコメントを // ERROR "message1|message2" という形式に更新した点にあります。

  • // ERROR "message1": これは、gcコンパイラがmessage1というエラーメッセージを生成することを期待するものです。
  • // ERROR "message1|message2": これは、gcコンパイラがmessage1を生成するか、またはgccgoコンパイラがmessage2を生成するかのいずれかの場合に、テストが成功することを意味します。パイプ|は論理ORとして機能し、指定された複数のエラーメッセージパターンのいずれかに一致すれば良いことを示します。

この変更により、テストスイートはより柔軟になり、gcgccgoの両方で同じテストケースを実行しても、エラーメッセージの表現のわずかな違いによってテストが失敗することがなくなります。これは、Go言語のコンパイラ実装が複数存在する環境において、テストの信頼性を維持するために不可欠なアプローチです。

また、一部のファイルでGC_ERRORERRORに、あるいはGCCGO_ERRORが追加されている点も重要です。

  • GC_ERRORからERRORへの変更: これは、以前はgc固有のエラーとして扱われていたものが、gccgoでも同様のエラーを報告するようになったため、より一般的なERRORコメントで対応できるようになったことを示します。
  • GCCGO_ERRORの追加: これは、そのエラーがgccgoに固有のものであり、gcでは発生しないか、異なる形で報告される場合に、gccgoでのみそのエラーを期待することを示します。

これらの変更は、Go言語のテストインフラストラクチャが、異なるコンパイラ実装の特性を考慮に入れ、テストの網羅性と互換性を高めるための継続的な努力の一環です。

関連リンク

参考にした情報源リンク

  • Go言語のテストに関するドキュメント (Goのソースコード内のテストガイドラインなど)
  • Go言語のコンパイラ実装に関する議論 (golang-devメーリングリストのアーカイブなど)
  • Go言語の仕様書 (特に型システム、複合リテラル、型変換に関するセクション)
  • GCCのドキュメント (コンパイラのエラー報告メカニズムに関する一般的な情報)
  • Go言語のunsafeパッケージに関するドキュメント
  • Go言語のswitch文に関するドキュメント
  • Go言語のif文に関するドキュメント
  • Go言語のインターフェースに関するドキュメント
  • Go言語の複合リテラルに関するドキュメント
  • Go言語の型変換に関するドキュメント
  • Go言語のテストフレームワークにおける// ERRORコメントの慣習に関する情報 (Goのテストファイル自体や、関連するコードレビューの議論から得られることが多い)
  • Go言語のコミット履歴とコードレビューシステム (Gerrit)
  • Go言語のIssue Tracker (バグ報告や機能要求の履歴)