SymABIs string "help:\"read symbol ABIs from `file`\""
TraceProfile string "help:\"write an execution trace to `file`\""
TrimPath string "help:\"remove `prefix` from recorded source file paths\""
- WB bool "help:\"enable write barrier\"" // TODO: remove
- OldComparable bool "help:\"enable old comparable semantics\"" // TODO: remove for Go 1.21
+ WB bool "help:\"enable write barrier\"" // TODO: remove
+ AltComparable bool "help:\"enable alternative comparable semantics\"" // experiment - remove eventually
PgoProfile string "help:\"read profile from `file`\""
// Configuration derived from flags; not a flag itself.
},
Importer: &importer,
Sizes: &gcSizes{},
- OldComparableSemantics: base.Flag.OldComparable, // default is new comparable semantics
+ AltComparableSemantics: base.Flag.AltComparable, // experiment - remove eventually
}
info := &types2.Info{
StoreTypesInSyntax: true,
// for unused imports.
DisableUnusedImportCheck bool
- // If OldComparableSemantics is set, ordinary (non-type parameter)
- // interfaces do not satisfy the comparable constraint.
- // TODO(gri) remove this flag for Go 1.21
- OldComparableSemantics bool
+ // If AltComparableSemantics is set, ordinary (non-type parameter)
+ // interfaces satisfy the comparable constraint.
+ AltComparableSemantics bool
}
func srcimporter_setUsesCgo(conf *Config) {
flags := flag.NewFlagSet("", flag.PanicOnError)
flags.StringVar(&conf.GoVersion, "lang", "", "")
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 {
t.Fatal(err)
}
// Only check comparability if we don't have a more specific error.
checkComparability := func() bool {
- if !Ti.IsComparable() {
- return true
- }
// If T is comparable, V must be comparable.
- // If V is strictly comparable, we're done.
- if comparable(V, false /* strict comparability */, nil, nil) {
- return true
- }
- // If check.conf.OldComparableSemantics is set (by the compiler or
- // 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 {
+ // For constraint satisfaction, use dynamic comparability for the
+ // alternative comparable semantics such that ordinary, non-type
+ // parameter interfaces implement comparable.
+ dynamic := constraint && check != nil && check.conf.AltComparableSemantics
+ if Ti.IsComparable() && !comparable(V, dynamic, nil, nil) {
if cause != nil {
*cause = check.sprintf("%s does not implement comparable", V)
}
return false
}
- // For constraint satisfaction, use dynamic (spec) comparability
- // 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
+ return true
}
// V must also be in the set of types of T, if any.
// for unused imports.
DisableUnusedImportCheck bool
- // If oldComparableSemantics is set, ordinary (non-type parameter)
- // interfaces do not satisfy the comparable constraint.
- // TODO(gri) remove this flag for Go 1.21
- oldComparableSemantics bool
+ // If altComparableSemantics is set, ordinary (non-type parameter)
+ // interfaces satisfy the comparable constraint.
+ altComparableSemantics bool
}
func srcimporter_setUsesCgo(conf *Config) {
flags := flag.NewFlagSet("", flag.PanicOnError)
flags.StringVar(&conf.GoVersion, "lang", "", "")
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 {
t.Fatal(err)
}
return int(v.FieldByName("go116code").Int())
}
-// addrOldComparableSemantics(conf) returns &conf.oldComparableSemantics (unexported field).
-func addrOldComparableSemantics(conf *Config) *bool {
+// addrAltComparableSemantics(conf) returns &conf.altComparableSemantics (unexported field).
+func addrAltComparableSemantics(conf *Config) *bool {
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
// Only check comparability if we don't have a more specific error.
checkComparability := func() bool {
- if !Ti.IsComparable() {
- return true
- }
// If T is comparable, V must be comparable.
- // If V is strictly comparable, we're done.
- if comparable(V, false /* strict comparability */, nil, nil) {
- return true
- }
- // If check.conf.OldComparableSemantics is set (by the compiler or
- // 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 {
+ // For constraint satisfaction, use dynamic comparability for the
+ // alternative comparable semantics such that ordinary, non-type
+ // parameter interfaces implement comparable.
+ dynamic := constraint && check != nil && check.conf.altComparableSemantics
+ if Ti.IsComparable() && !comparable(V, dynamic, nil, nil) {
if cause != nil {
*cause = check.sprintf("%s does not implement comparable", V)
}
return false
}
- // For constraint satisfaction, use dynamic (spec) comparability
- // 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
+ return true
}
// V must also be in the set of types of T, if any.
-// -oldComparableSemantics
-
// Copyright 2020 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.
-// -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.
-// -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.
+// -altComparableSemantics
+
// 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.
+++ /dev/null
-// -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 */]
-}
+++ /dev/null
-// -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 */]
-}