From de47f68c99e9c86a32261b45752819a86cac74f2 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Fri, 21 Jun 2013 16:11:13 -0700 Subject: [PATCH] spec: fix spec on conversions to match implementations The existing compilers convert empty strings to empty but non-nil byte and rune slices. The spec required a nil byte and rune slice in those cases. That seems an odd additional requirement. Adjust the spec to match the reality. Also, removed over-specification for conversions of nil []byte and []rune: such nil slices already act like empty slices and thus don't need extra language. Added extra examples instead. Fixes #5704. R=rsc, r, iant CC=golang-dev https://golang.org/cl/10440045 --- doc/go_spec.html | 23 +++++++++++-------- test/fixedbugs/issue5704.go | 46 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 test/fixedbugs/issue5704.go diff --git a/doc/go_spec.html b/doc/go_spec.html index 1e45e73d48..a1dc7d8b19 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -3735,11 +3735,12 @@ MyString(0x65e5) // "\u65e5" == "日" == "\xe6\x97\xa5"
  • Converting a slice of bytes to a string type yields -a string whose successive bytes are the elements of the slice. If -the slice value is nil, the result is the empty string. +a string whose successive bytes are the elements of the slice.
    -string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'})  // "hellø"
    +string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'})   // "hellø"
    +string([]byte{})                                     // ""
    +string([]byte(nil))                                  // ""
     
     type MyBytes []byte
     string(MyBytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'})  // "hellø"
    @@ -3749,11 +3750,12 @@ string(MyBytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'})  // "hellø"
     
  • Converting a slice of runes to a string type yields a string that is the concatenation of the individual rune values -converted to strings. If the slice value is nil, the -result is the empty string. +converted to strings.
    -string([]rune{0x767d, 0x9d6c, 0x7fd4})  // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +string([]rune{0x767d, 0x9d6c, 0x7fd4})   // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +string([]rune{})                         // ""
    +string([]rune(nil))                      // ""
     
     type MyRunes []rune
     string(MyRunes{0x767d, 0x9d6c, 0x7fd4})  // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    @@ -3763,10 +3765,11 @@ string(MyRunes{0x767d, 0x9d6c, 0x7fd4})  // "\u767d\u9d6c\u7fd4" == "白鵬翔"
     
  • Converting a value of a string type to a slice of bytes type yields a slice whose successive elements are the bytes of the string. -If the string is empty, the result is []byte(nil).
     []byte("hellø")   // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
    +[]byte("")        // []byte{}
    +
     MyBytes("hellø")  // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
     
  • @@ -3774,9 +3777,11 @@ MyBytes("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
  • Converting a value of a string type to a slice of runes type yields a slice containing the individual Unicode code points of the string. -If the string is empty, the result is []rune(nil). +
     []rune(MyString("白鵬翔"))  // []rune{0x767d, 0x9d6c, 0x7fd4}
    +[]rune("")                 // []rune{}
    +
     MyRunes("白鵬翔")           // []rune{0x767d, 0x9d6c, 0x7fd4}
     
  • diff --git a/test/fixedbugs/issue5704.go b/test/fixedbugs/issue5704.go new file mode 100644 index 0000000000..1dfa072143 --- /dev/null +++ b/test/fixedbugs/issue5704.go @@ -0,0 +1,46 @@ +// run + +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 5704: Conversions of empty strings to byte +// or rune slices return empty but non-nil slices. + +package main + +type ( + mystring string + mybytes []byte + myrunes []rune +) + +func checkBytes(s []byte, arg string) { + if len(s) != 0 { + panic("len(" + arg + ") != 0") + } + if s == nil { + panic(arg + " == nil") + } +} + +func checkRunes(s []rune, arg string) { + if len(s) != 0 { + panic("len(" + arg + ") != 0") + } + if s == nil { + panic(arg + " == nil") + } +} + +func main() { + checkBytes([]byte(""), `[]byte("")`) + checkBytes([]byte(mystring("")), `[]byte(mystring(""))`) + checkBytes(mybytes(""), `mybytes("")`) + checkBytes(mybytes(mystring("")), `mybytes(mystring(""))`) + + checkRunes([]rune(""), `[]rune("")`) + checkRunes([]rune(mystring("")), `[]rune(mystring(""))`) + checkRunes(myrunes(""), `myrunes("")`) + checkRunes(myrunes(mystring("")), `myrunes(mystring(""))`) +} -- 2.48.1