]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile, types2: avoid confusing follow-on error in invalid type assertion
authorRobert Griesemer <gri@golang.org>
Sun, 17 Oct 2021 03:30:12 +0000 (20:30 -0700)
committerRobert Griesemer <gri@golang.org>
Sun, 17 Oct 2021 04:27:13 +0000 (04:27 +0000)
This CL avoids a useless follow-on error (that gets reported before the
actual error due to source position). This addresses the first part of
the issue below.

Thanks to @cuonglm for the suggestion for the fix.

For #49005.

Change-Id: Ifdd83072a05c32e115dc58a0233868a64f336f3f
Reviewed-on: https://go-review.googlesource.com/c/go/+/356449
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
src/cmd/compile/internal/types2/typexpr.go
test/fixedbugs/issue49005a.go [new file with mode: 0644]

index 646becbdae07b8014b751905555a16228defa9e1..eae93309147f567fd1a150172119ddae91de8c1e 100644 (file)
@@ -312,6 +312,13 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
                        typ := new(Pointer)
                        def.setUnderlying(typ)
                        typ.base = check.varType(e.X)
+                       // If typ.base is invalid, it's unlikely that *base is particularly
+                       // useful - even a valid dereferenciation will lead to an invalid
+                       // type again, and in some cases we get unexpected follow-on errors
+                       // (e.g., see #49005). Return an invalid type instead.
+                       if typ.base == Typ[Invalid] {
+                               return Typ[Invalid]
+                       }
                        return typ
                }
 
diff --git a/test/fixedbugs/issue49005a.go b/test/fixedbugs/issue49005a.go
new file mode 100644 (file)
index 0000000..55d92c4
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+package p
+
+type T interface{ M() }
+
+func F() T
+
+var _ = F().(*X) // ERROR "undefined: X"