From 9dc88fb721c35b3db892d876507f1e3f0fe01d10 Mon Sep 17 00:00:00 2001 From: Adam Williams Date: Thu, 9 Jan 2020 17:08:47 -0700 Subject: [PATCH] cmd/stringer: remove redundant check in generated code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a certain case, stringer would generate the following check for an an unsigned integer i: "0 <= i". This changes stringer to not generate such a check. Also adds an additional test case for an unsigned multiple run that does not include zero. There was already a case ("unum") that included an unsigned multiple run starting at zero. This case's output was updated accordingly. Fixes golang/go#36461 Change-Id: I57e79384a0b802fa4571e2b3495db168b814bcaa Reviewed-on: https://go-review.googlesource.com/c/tools/+/214180 Run-TryBot: Daniel Martí TryBot-Result: Gobot Gobot Reviewed-by: Daniel Martí --- cmd/stringer/golden_test.go | 52 ++++++++++++++++++++++++++++++++++++- cmd/stringer/stringer.go | 7 ++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/cmd/stringer/golden_test.go b/cmd/stringer/golden_test.go index ff0f6682ba..b29763174b 100644 --- a/cmd/stringer/golden_test.go +++ b/cmd/stringer/golden_test.go @@ -34,6 +34,7 @@ var golden = []Golden{ {"gap", "", false, gap_in, gap_out}, {"num", "", false, num_in, num_out}, {"unum", "", false, unum_in, unum_out}, + {"unumpos", "", false, unumpos_in, unumpos_out}, {"prime", "", false, prime_in, prime_out}, {"prefix", "Type", false, prefix_in, prefix_out}, {"tokens", "", true, tokens_in, tokens_out}, @@ -240,7 +241,7 @@ var ( func (i Unum) String() string { switch { - case 0 <= i && i <= 2: + case i <= 2: return _Unum_name_0[_Unum_index_0[i]:_Unum_index_0[i+1]] case 253 <= i && i <= 254: i -= 253 @@ -251,6 +252,55 @@ func (i Unum) String() string { } ` +// Unsigned positive integers. +const unumpos_in = `type Unumpos uint +const ( + m253 Unumpos = iota + 253 + m254 +) + +const ( + m1 Unumpos = iota + 1 + m2 + m3 +) +` + +const unumpos_out = `func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[m253-253] + _ = x[m254-254] + _ = x[m1-1] + _ = x[m2-2] + _ = x[m3-3] +} + +const ( + _Unumpos_name_0 = "m1m2m3" + _Unumpos_name_1 = "m253m254" +) + +var ( + _Unumpos_index_0 = [...]uint8{0, 2, 4, 6} + _Unumpos_index_1 = [...]uint8{0, 4, 8} +) + +func (i Unumpos) String() string { + switch { + case 1 <= i && i <= 3: + i -= 1 + return _Unumpos_name_0[_Unumpos_index_0[i]:_Unumpos_index_0[i+1]] + case 253 <= i && i <= 254: + i -= 253 + return _Unumpos_name_1[_Unumpos_index_1[i]:_Unumpos_index_1[i+1]] + default: + return "Unumpos(" + strconv.FormatInt(int64(i), 10) + ")" + } +} +` + // Enough gaps to trigger a map implementation of the method. // Also includes a duplicate to test that it doesn't cause problems const prime_in = `type Prime int diff --git a/cmd/stringer/stringer.go b/cmd/stringer/stringer.go index e1468693f0..a5cd587e4b 100644 --- a/cmd/stringer/stringer.go +++ b/cmd/stringer/stringer.go @@ -610,7 +610,12 @@ func (g *Generator) buildMultipleRuns(runs [][]Value, typeName string) { g.Printf("\t\treturn _%s_name_%d\n", typeName, i) continue } - g.Printf("\tcase %s <= i && i <= %s:\n", &values[0], &values[len(values)-1]) + if values[0].value == 0 && !values[0].signed { + // For an unsigned lower bound of 0, "0 <= i" would be redundant. + g.Printf("\tcase i <= %s:\n", &values[len(values)-1]) + } else { + g.Printf("\tcase %s <= i && i <= %s:\n", &values[0], &values[len(values)-1]) + } if values[0].value != 0 { g.Printf("\t\ti -= %s\n", &values[0]) }