Skip to content

Commit

Permalink
[dev.typeparams] cmd/compile/internal/types2: remove MethodSet code -…
Browse files Browse the repository at this point in the history
… not used by types2

We can always re-introduce it if we decide to make use of it.

Change-Id: Ia939fdae978568edc58e21d1af732c6137744aab
Reviewed-on: https://go-review.googlesource.com/c/go/+/285678
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
  • Loading branch information
griesemer committed Jan 23, 2021
1 parent 5347241 commit a49e941
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 365 deletions.
5 changes: 2 additions & 3 deletions src/cmd/compile/internal/importer/gcimporter_test.go
Expand Up @@ -384,9 +384,8 @@ func TestCorrectMethodPackage(t *testing.T) {
}

mutex := imports["sync"].Scope().Lookup("Mutex").(*types2.TypeName).Type()
mset := types2.NewMethodSet(types2.NewPointer(mutex)) // methods of *sync.Mutex
sel := mset.Lookup(nil, "Lock")
lock := sel.Obj().(*types2.Func)
obj, _, _ := types2.LookupFieldOrMethod(types2.NewPointer(mutex), false, nil, "Lock")
lock := obj.(*types2.Func)
if got, want := lock.Pkg().Path(), "sync"; got != want {
t.Errorf("got package path %q; want %q", got, want)
}
Expand Down
45 changes: 0 additions & 45 deletions src/cmd/compile/internal/types2/call.go
Expand Up @@ -685,51 +685,6 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr) {
// addressability, should we report the type &(x.typ) instead?
check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)

// TODO(gri) The verification pass below is disabled for now because
// method sets don't match method lookup in some cases.
// For instance, if we made a copy above when creating a
// custom method for a parameterized received type, the
// method set method doesn't match (no copy there). There
/// may be other situations.
disabled := true
if !disabled && debug {
// Verify that LookupFieldOrMethod and MethodSet.Lookup agree.
// TODO(gri) This only works because we call LookupFieldOrMethod
// _before_ calling NewMethodSet: LookupFieldOrMethod completes
// any incomplete interfaces so they are available to NewMethodSet
// (which assumes that interfaces have been completed already).
typ := x.typ
if x.mode == variable {
// If typ is not an (unnamed) pointer or an interface,
// use *typ instead, because the method set of *typ
// includes the methods of typ.
// Variables are addressable, so we can always take their
// address.
if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
typ = &Pointer{base: typ}
}
}
// If we created a synthetic pointer type above, we will throw
// away the method set computed here after use.
// TODO(gri) Method set computation should probably always compute
// both, the value and the pointer receiver method set and represent
// them in a single structure.
// TODO(gri) Consider also using a method set cache for the lifetime
// of checker once we rely on MethodSet lookup instead of individual
// lookup.
mset := NewMethodSet(typ)
if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
check.dump("%v: (%s).%v -> %s", posFor(e), typ, obj.name, m)
check.dump("%s\n", mset)
// Caution: MethodSets are supposed to be used externally
// only (after all interface types were completed). It's
// now possible that we get here incorrectly. Not urgent
// to fix since we only run this code in debug mode.
// TODO(gri) fix this eventually.
panic("method sets and lookup don't agree")
}
}

x.mode = value

// remove receiver
Expand Down
55 changes: 0 additions & 55 deletions src/cmd/compile/internal/types2/example_test.go
Expand Up @@ -107,61 +107,6 @@ func Unused() { {}; {{ var x int; _ = x }} } // make sure empty block scopes get
// }
}

// ExampleMethodSet prints the method sets of various types.
func ExampleMethodSet() {
// Parse a single source file.
const input = `
package temperature
import "fmt"
type Celsius float64
func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }
func (c *Celsius) SetF(f float64) { *c = Celsius(f - 32 / 9 * 5) }
type S struct { I; m int }
type I interface { m() byte }
`
f, err := parseSrc("celsius.go", input)
if err != nil {
log.Fatal(err)
}

// Type-check a package consisting of this file.
// Type information for the imported packages
// comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a.
conf := types2.Config{Importer: defaultImporter()}
pkg, err := conf.Check("temperature", []*syntax.File{f}, nil)
if err != nil {
log.Fatal(err)
}

// Print the method sets of Celsius and *Celsius.
celsius := pkg.Scope().Lookup("Celsius").Type()
for _, t := range []types2.Type{celsius, types2.NewPointer(celsius)} {
fmt.Printf("Method set of %s:\n", t)
mset := types2.NewMethodSet(t)
for i := 0; i < mset.Len(); i++ {
fmt.Println(mset.At(i))
}
fmt.Println()
}

// Print the method set of S.
styp := pkg.Scope().Lookup("S").Type()
fmt.Printf("Method set of %s:\n", styp)
fmt.Println(types2.NewMethodSet(styp))

// Output:
// Method set of temperature.Celsius:
// method (temperature.Celsius) String() string
//
// Method set of *temperature.Celsius:
// method (*temperature.Celsius) SetF(f float64)
// method (*temperature.Celsius) String() string
//
// Method set of temperature.S:
// MethodSet {}
}

// ExampleInfo prints various facts recorded by the type checker in a
// types2.Info struct: definitions of and references to each named object,
// and the type, value, and mode of every expression in the package.
Expand Down
19 changes: 19 additions & 0 deletions src/cmd/compile/internal/types2/lookup.go
Expand Up @@ -491,3 +491,22 @@ func lookupMethod(methods []*Func, pkg *Package, name string) (int, *Func) {
}
return -1, nil
}

// ptrRecv reports whether the receiver is of the form *T.
func ptrRecv(f *Func) bool {
// If a method's receiver type is set, use that as the source of truth for the receiver.
// Caution: Checker.funcDecl (decl.go) marks a function by setting its type to an empty
// signature. We may reach here before the signature is fully set up: we must explicitly
// check if the receiver is set (we cannot just look for non-nil f.typ).
if sig, _ := f.typ.(*Signature); sig != nil && sig.recv != nil {
_, isPtr := deref(sig.recv.typ)
return isPtr
}

// If a method's type is not set it may be a method/function that is:
// 1) client-supplied (via NewFunc with no signature), or
// 2) internally created but not yet type-checked.
// For case 1) we can't do anything; the client must know what they are doing.
// For case 2) we can use the information gathered by the resolver.
return f.hasPtrRecv
}

0 comments on commit a49e941

Please sign in to comment.