From 60dd831103cbb98acc322804847306ab7ce8e048 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 16 Aug 2023 11:17:01 -0700 Subject: [PATCH] Revert "go/types, types2: remove internal constant enableInterfaceInference" This reverts CL 514715. This will make it easier to make interface inference conditional based on the current language version. For #61903. Change-Id: I07820c861d6ebfd04899e41eb4123f26af2da1ee Reviewed-on: https://go-review.googlesource.com/c/go/+/520195 Reviewed-by: Robert Findley Auto-Submit: Robert Griesemer Reviewed-by: Robert Griesemer TryBot-Result: Gopher Robot Run-TryBot: Robert Griesemer --- src/cmd/compile/internal/types2/unify.go | 17 +++++++++++------ src/go/types/unify.go | 17 +++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/cmd/compile/internal/types2/unify.go b/src/cmd/compile/internal/types2/unify.go index 6a130d55e0..be5796bc32 100644 --- a/src/cmd/compile/internal/types2/unify.go +++ b/src/cmd/compile/internal/types2/unify.go @@ -53,6 +53,11 @@ const ( // the core types, if any, of non-local (unbound) type parameters. enableCoreTypeUnification = true + // If enableInterfaceInference is set, type inference uses + // shared methods for improved type inference involving + // interfaces. + enableInterfaceInference = true + // If traceInference is set, unification will print a trace of its operation. // Interpretation of trace: // x ≡ y attempt to unify types x and y @@ -334,7 +339,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { // we will fail at function instantiation or argument assignment time. // // If we have at least one defined type, there is one in y. - if ny, _ := y.(*Named); mode&exact == 0 && ny != nil && isTypeLit(x) && !IsInterface(x) { + if ny, _ := y.(*Named); mode&exact == 0 && ny != nil && isTypeLit(x) && !(enableInterfaceInference && IsInterface(x)) { if traceInference { u.tracef("%s ≡ under %s", x, ny) } @@ -425,12 +430,12 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { // x != y if we get here assert(x != y) - // If we don't require exact unification and both types are interfaces, - // one interface must have a subset of the methods of the other and - // corresponding method signatures must unify. + // If EnableInterfaceInference is set and we don't require exact unification, + // if both types are interfaces, one interface must have a subset of the + // methods of the other and corresponding method signatures must unify. // If only one type is an interface, all its methods must be present in the // other type and corresponding method signatures must unify. - if mode&exact == 0 { + if enableInterfaceInference && mode&exact == 0 { // One or both interfaces may be defined types. // Look under the name, but not under type parameters (go.dev/issue/60564). xi := asInterface(x) @@ -627,7 +632,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { } case *Interface: - assert(mode&exact != 0) // inexact unification is handled before this switch + assert(!enableInterfaceInference || mode&exact != 0) // handled before this switch // Two interface types unify if they have the same set of methods with // the same names, and corresponding function types unify. diff --git a/src/go/types/unify.go b/src/go/types/unify.go index 20381215c5..6d4a69e522 100644 --- a/src/go/types/unify.go +++ b/src/go/types/unify.go @@ -55,6 +55,11 @@ const ( // the core types, if any, of non-local (unbound) type parameters. enableCoreTypeUnification = true + // If enableInterfaceInference is set, type inference uses + // shared methods for improved type inference involving + // interfaces. + enableInterfaceInference = true + // If traceInference is set, unification will print a trace of its operation. // Interpretation of trace: // x ≡ y attempt to unify types x and y @@ -336,7 +341,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { // we will fail at function instantiation or argument assignment time. // // If we have at least one defined type, there is one in y. - if ny, _ := y.(*Named); mode&exact == 0 && ny != nil && isTypeLit(x) && !IsInterface(x) { + if ny, _ := y.(*Named); mode&exact == 0 && ny != nil && isTypeLit(x) && !(enableInterfaceInference && IsInterface(x)) { if traceInference { u.tracef("%s ≡ under %s", x, ny) } @@ -427,12 +432,12 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { // x != y if we get here assert(x != y) - // If we don't require exact unification and both types are interfaces, - // one interface must have a subset of the methods of the other and - // corresponding method signatures must unify. + // If EnableInterfaceInference is set and we don't require exact unification, + // if both types are interfaces, one interface must have a subset of the + // methods of the other and corresponding method signatures must unify. // If only one type is an interface, all its methods must be present in the // other type and corresponding method signatures must unify. - if mode&exact == 0 { + if enableInterfaceInference && mode&exact == 0 { // One or both interfaces may be defined types. // Look under the name, but not under type parameters (go.dev/issue/60564). xi := asInterface(x) @@ -629,7 +634,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { } case *Interface: - assert(mode&exact != 0) // inexact unification is handled before this switch + assert(!enableInterfaceInference || mode&exact != 0) // handled before this switch // Two interface types unify if they have the same set of methods with // the same names, and corresponding function types unify. -- 2.48.1