1
0
mirror of https://github.com/golang/go synced 2024-09-30 11:18:33 -06:00

Revert "go/types, types2: make the new comparable semantics the default"

The CL below was accidentally submitted, while waiting for the freeze
exception. Reverting.

This reverts commit 15e705ea96.

Change-Id: I4dbf92dcb01fa9245a6e6a2d1514d8aa898d0048
Reviewed-on: https://go-review.googlesource.com/c/go/+/454476
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Robert Griesemer <gri@google.com>
This commit is contained in:
Robert Griesemer 2022-12-01 09:09:37 -08:00 committed by Gopher Robot
parent f5026496cf
commit 2ca32a5b99
14 changed files with 28 additions and 132 deletions

View File

@ -122,8 +122,8 @@ type CmdFlags struct {
SymABIs string "help:\"read symbol ABIs from `file`\"" SymABIs string "help:\"read symbol ABIs from `file`\""
TraceProfile string "help:\"write an execution trace to `file`\"" TraceProfile string "help:\"write an execution trace to `file`\""
TrimPath string "help:\"remove `prefix` from recorded source file paths\"" TrimPath string "help:\"remove `prefix` from recorded source file paths\""
WB bool "help:\"enable write barrier\"" // TODO: remove WB bool "help:\"enable write barrier\"" // TODO: remove
OldComparable bool "help:\"enable old comparable semantics\"" // TODO: remove for Go 1.21 AltComparable bool "help:\"enable alternative comparable semantics\"" // experiment - remove eventually
PgoProfile string "help:\"read profile from `file`\"" PgoProfile string "help:\"read profile from `file`\""
// Configuration derived from flags; not a flag itself. // Configuration derived from flags; not a flag itself.

View File

@ -57,7 +57,7 @@ func checkFiles(noders []*noder) (posMap, *types2.Package, *types2.Info) {
}, },
Importer: &importer, Importer: &importer,
Sizes: &gcSizes{}, Sizes: &gcSizes{},
OldComparableSemantics: base.Flag.OldComparable, // default is new comparable semantics AltComparableSemantics: base.Flag.AltComparable, // experiment - remove eventually
} }
info := &types2.Info{ info := &types2.Info{
StoreTypesInSyntax: true, StoreTypesInSyntax: true,

View File

@ -168,10 +168,9 @@ type Config struct {
// for unused imports. // for unused imports.
DisableUnusedImportCheck bool DisableUnusedImportCheck bool
// If OldComparableSemantics is set, ordinary (non-type parameter) // If AltComparableSemantics is set, ordinary (non-type parameter)
// interfaces do not satisfy the comparable constraint. // interfaces satisfy the comparable constraint.
// TODO(gri) remove this flag for Go 1.21 AltComparableSemantics bool
OldComparableSemantics bool
} }
func srcimporter_setUsesCgo(conf *Config) { func srcimporter_setUsesCgo(conf *Config) {

View File

@ -130,7 +130,7 @@ func testFiles(t *testing.T, filenames []string, colDelta uint, manual bool) {
flags := flag.NewFlagSet("", flag.PanicOnError) flags := flag.NewFlagSet("", flag.PanicOnError)
flags.StringVar(&conf.GoVersion, "lang", "", "") flags.StringVar(&conf.GoVersion, "lang", "", "")
flags.BoolVar(&conf.FakeImportC, "fakeImportC", false, "") flags.BoolVar(&conf.FakeImportC, "fakeImportC", false, "")
flags.BoolVar(&conf.OldComparableSemantics, "oldComparableSemantics", false, "") flags.BoolVar(&conf.AltComparableSemantics, "altComparableSemantics", false, "")
if err := parseFlags(filenames[0], nil, flags); err != nil { if err := parseFlags(filenames[0], nil, flags); err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -245,39 +245,18 @@ func (check *Checker) implements(V, T Type, constraint bool, cause *string) bool
// Only check comparability if we don't have a more specific error. // Only check comparability if we don't have a more specific error.
checkComparability := func() bool { checkComparability := func() bool {
if !Ti.IsComparable() {
return true
}
// If T is comparable, V must be comparable. // If T is comparable, V must be comparable.
// If V is strictly comparable, we're done. // For constraint satisfaction, use dynamic comparability for the
if comparable(V, false /* strict comparability */, nil, nil) { // alternative comparable semantics such that ordinary, non-type
return true // parameter interfaces implement comparable.
} dynamic := constraint && check != nil && check.conf.AltComparableSemantics
// If check.conf.OldComparableSemantics is set (by the compiler or if Ti.IsComparable() && !comparable(V, dynamic, nil, nil) {
// a test), we only consider strict comparability and we're done.
// TODO(gri) remove this check for Go 1.21
if check != nil && check.conf.OldComparableSemantics {
if cause != nil { if cause != nil {
*cause = check.sprintf("%s does not implement comparable", V) *cause = check.sprintf("%s does not implement comparable", V)
} }
return false return false
} }
// For constraint satisfaction, use dynamic (spec) comparability return true
// so that ordinary, non-type parameter interfaces implement comparable.
if constraint && comparable(V, true /* spec comparability */, nil, nil) {
// V is comparable if we are at Go 1.20 or higher.
if check == nil || check.allowVersion(check.pkg, 1, 20) {
return true
}
if cause != nil {
*cause = check.sprintf("%s to implement comparable requires go1.20 or later", V)
}
return false
}
if cause != nil {
*cause = check.sprintf("%s does not implement comparable", V)
}
return false
} }
// V must also be in the set of types of T, if any. // V must also be in the set of types of T, if any.

View File

@ -168,10 +168,9 @@ type Config struct {
// for unused imports. // for unused imports.
DisableUnusedImportCheck bool DisableUnusedImportCheck bool
// If oldComparableSemantics is set, ordinary (non-type parameter) // If altComparableSemantics is set, ordinary (non-type parameter)
// interfaces do not satisfy the comparable constraint. // interfaces satisfy the comparable constraint.
// TODO(gri) remove this flag for Go 1.21 altComparableSemantics bool
oldComparableSemantics bool
} }
func srcimporter_setUsesCgo(conf *Config) { func srcimporter_setUsesCgo(conf *Config) {

View File

@ -217,7 +217,7 @@ func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, man
flags := flag.NewFlagSet("", flag.PanicOnError) flags := flag.NewFlagSet("", flag.PanicOnError)
flags.StringVar(&conf.GoVersion, "lang", "", "") flags.StringVar(&conf.GoVersion, "lang", "", "")
flags.BoolVar(&conf.FakeImportC, "fakeImportC", false, "") flags.BoolVar(&conf.FakeImportC, "fakeImportC", false, "")
flags.BoolVar(addrOldComparableSemantics(&conf), "oldComparableSemantics", false, "") flags.BoolVar(addrAltComparableSemantics(&conf), "altComparableSemantics", false, "")
if err := parseFlags(filenames[0], srcs[0], flags); err != nil { if err := parseFlags(filenames[0], srcs[0], flags); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -294,10 +294,10 @@ func readCode(err Error) int {
return int(v.FieldByName("go116code").Int()) return int(v.FieldByName("go116code").Int())
} }
// addrOldComparableSemantics(conf) returns &conf.oldComparableSemantics (unexported field). // addrAltComparableSemantics(conf) returns &conf.altComparableSemantics (unexported field).
func addrOldComparableSemantics(conf *Config) *bool { func addrAltComparableSemantics(conf *Config) *bool {
v := reflect.Indirect(reflect.ValueOf(conf)) v := reflect.Indirect(reflect.ValueOf(conf))
return (*bool)(v.FieldByName("oldComparableSemantics").Addr().UnsafePointer()) return (*bool)(v.FieldByName("altComparableSemantics").Addr().UnsafePointer())
} }
// TestManual is for manual testing of a package - either provided // TestManual is for manual testing of a package - either provided

View File

@ -245,39 +245,18 @@ func (check *Checker) implements(V, T Type, constraint bool, cause *string) bool
// Only check comparability if we don't have a more specific error. // Only check comparability if we don't have a more specific error.
checkComparability := func() bool { checkComparability := func() bool {
if !Ti.IsComparable() {
return true
}
// If T is comparable, V must be comparable. // If T is comparable, V must be comparable.
// If V is strictly comparable, we're done. // For constraint satisfaction, use dynamic comparability for the
if comparable(V, false /* strict comparability */, nil, nil) { // alternative comparable semantics such that ordinary, non-type
return true // parameter interfaces implement comparable.
} dynamic := constraint && check != nil && check.conf.altComparableSemantics
// If check.conf.OldComparableSemantics is set (by the compiler or if Ti.IsComparable() && !comparable(V, dynamic, nil, nil) {
// a test), we only consider strict comparability and we're done.
// TODO(gri) remove this check for Go 1.21
if check != nil && check.conf.oldComparableSemantics {
if cause != nil { if cause != nil {
*cause = check.sprintf("%s does not implement comparable", V) *cause = check.sprintf("%s does not implement comparable", V)
} }
return false return false
} }
// For constraint satisfaction, use dynamic (spec) comparability return true
// so that ordinary, non-type parameter interfaces implement comparable.
if constraint && comparable(V, true /* spec comparability */, nil, nil) {
// V is comparable if we are at Go 1.20 or higher.
if check == nil || check.allowVersion(check.pkg, 1, 20) {
return true
}
if cause != nil {
*cause = check.sprintf("%s to implement comparable requires go1.20 or later", V)
}
return false
}
if cause != nil {
*cause = check.sprintf("%s does not implement comparable", V)
}
return false
} }
// V must also be in the set of types of T, if any. // V must also be in the set of types of T, if any.

View File

@ -1,5 +1,3 @@
// -oldComparableSemantics
// Copyright 2020 The Go Authors. All rights reserved. // Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,5 +1,3 @@
// -oldComparableSemantics
// Copyright 2022 The Go Authors. All rights reserved. // Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,5 +1,3 @@
// -oldComparableSemantics
// Copyright 2022 The Go Authors. All rights reserved. // Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,3 +1,5 @@
// -altComparableSemantics
// Copyright 2022 The Go Authors. All rights reserved. // Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,28 +0,0 @@
// -lang=go1.19
// Copyright 2022 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.
package p
func f1[_ comparable]() {}
func f2[_ interface{ comparable }]() {}
type T interface{ m() }
func _[P comparable, Q ~int, R any]() {
_ = f1[int]
_ = f1[T /* ERROR T to implement comparable requires go1\.20 or later */]
_ = f1[any /* ERROR any to implement comparable requires go1\.20 or later */]
_ = f1[P]
_ = f1[Q]
_ = f1[R /* ERROR R does not implement comparable */]
_ = f2[int]
_ = f2[T /* ERROR T to implement comparable requires go1\.20 or later */]
_ = f2[any /* ERROR any to implement comparable requires go1\.20 or later */]
_ = f2[P]
_ = f2[Q]
_ = f2[R /* ERROR R does not implement comparable */]
}

View File

@ -1,28 +0,0 @@
// -oldComparableSemantics
// Copyright 2022 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.
package p
func f1[_ comparable]() {}
func f2[_ interface{ comparable }]() {}
type T interface{ m() }
func _[P comparable, Q ~int, R any]() {
_ = f1[int]
_ = f1[T /* ERROR T does not implement comparable */]
_ = f1[any /* ERROR any does not implement comparable */]
_ = f1[P]
_ = f1[Q]
_ = f1[R /* ERROR R does not implement comparable */]
_ = f2[int]
_ = f2[T /* ERROR T does not implement comparable */]
_ = f2[any /* ERROR any does not implement comparable */]
_ = f2[P]
_ = f2[Q]
_ = f2[R /* ERROR R does not implement comparable */]
}