From 6a41d32189ed90822cf9d6d9d5bb8a67f3531c17 Mon Sep 17 00:00:00 2001 From: HowJMay Date: Fri, 22 Jan 2021 01:12:51 +0800 Subject: [PATCH] cmd/compile: revise error msg in type assertion ptr/non-ptr condition Revise the error message under the condition that type assertion has mismatching pointer/non-pointer type. This adds a better error hint for the situation that a user writes x.(*I), but they meant to write x.(I). Fixes #43673 --- src/cmd/compile/internal/gc/typecheck.go | 7 ++++++- test/fixedbugs/issue43831.go | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue43831.go diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index c0b05035f033c1..a12caaa42be550 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -999,7 +999,12 @@ func typecheck1(n *Node, top int) (res *Node) { yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+ "\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) } else { - yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type, t, missing.Sym) + origMissing := missing + if implements(derefall(n.Type), t, &missing, &have, &ptr) { + yyerror("impossible type assertion:\n\t%v does not implement %v method (but %v does)", n.Type, missing.Sym, derefall(n.Type)) + } else { + yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type, t, origMissing.Sym) + } } n.Type = nil return n diff --git a/test/fixedbugs/issue43831.go b/test/fixedbugs/issue43831.go new file mode 100644 index 00000000000000..fabc687e2435b5 --- /dev/null +++ b/test/fixedbugs/issue43831.go @@ -0,0 +1,21 @@ +// errorcheck + +// Copyright 2021 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. + +// Issue 43831 +package main + +type I interface { + M() +} + +type T struct{} + +func (t *T) M() {} + +func main() { + var i I + _ = i.(*I) // ERROR "*I does not implement M method (but I does)" +}