diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index 3fc59194e412cd81aa36c30afe1a43f5b04e646c..27326f67a1143674bfbd2f341f0b4284fad20f70 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -1189,7 +1189,12 @@ func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) } } - u = methtype(t) + u = t + if t.Sym != nil && t.IsPtr() && !t.Elem().IsPtr() { + // If t is a defined pointer type, then x.m is shorthand for (*x).m. + u = t.Elem() + } + u = methtype(u) if u != nil { for _, f := range u.Methods().Slice() { if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) { diff --git a/test/fixedbugs/issue21934.go b/test/fixedbugs/issue21934.go new file mode 100644 index 0000000000000000000000000000000000000000..e9a430f18f98bbbd1e52910d8100bc8515f1e02c --- /dev/null +++ b/test/fixedbugs/issue21934.go @@ -0,0 +1,26 @@ +// errorcheck + +// Copyright 2019 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. + +// selector expression resolves incorrectly for defined +// pointer types. + +package main + +type E struct{ f int } +type T struct{ E } + +func (*T) f() int { return 0 } + +type P *T +type PP **T + +func main() { + var x P + _ = x.f // ERROR "x\.f undefined \(type P has no field or method f\)" + + var y PP + _ = y.f // ERROR "y\.f undefined \(type PP has no field or method f\)" +}