From 38db0316f4e45704cc891026ea28dd566387de95 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Tue, 3 Oct 2023 21:54:48 +0700 Subject: [PATCH] cmd/compile: do not fatal when typechecking conversion expression The types2 typechecker already reported all invalid conversions required by the Go language spec. However, the conversion involves go pragma is not specified in the spec, so is not checked by types2. Fixing this by handling the error gracefully during typecheck, just like how old typechecker did before CL 394575. Fixes #63333 Change-Id: I04c4121971c62d96f75ded1794ab4bdf3a6cd0ea Reviewed-on: https://go-review.googlesource.com/c/go/+/532515 Auto-Submit: Cuong Manh Le LUCI-TryBot-Result: Go LUCI Reviewed-by: Matthew Dempsky Reviewed-by: Keith Randall TryBot-Result: Gopher Robot Run-TryBot: Cuong Manh Le --- src/cmd/compile/internal/typecheck/expr.go | 6 +++++- test/fixedbugs/issue63333.go | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue63333.go diff --git a/src/cmd/compile/internal/typecheck/expr.go b/src/cmd/compile/internal/typecheck/expr.go index 53d0cbf96d..83d1355fe5 100644 --- a/src/cmd/compile/internal/typecheck/expr.go +++ b/src/cmd/compile/internal/typecheck/expr.go @@ -8,6 +8,7 @@ import ( "fmt" "go/constant" "go/token" + "internal/types/errors" "strings" "cmd/compile/internal/base" @@ -353,7 +354,10 @@ func tcConv(n *ir.ConvExpr) ir.Node { } op, why := Convertop(n.X.Op() == ir.OLITERAL, t, n.Type()) if op == ir.OXXX { - base.Fatalf("cannot convert %L to type %v%s", n.X, n.Type(), why) + // Due to //go:nointerface, we may be stricter than types2 here (#63333). + base.ErrorfAt(n.Pos(), errors.InvalidConversion, "cannot convert %L to type %v%s", n.X, n.Type(), why) + n.SetType(nil) + return n } n.SetOp(op) diff --git a/test/fixedbugs/issue63333.go b/test/fixedbugs/issue63333.go new file mode 100644 index 0000000000..e14b367430 --- /dev/null +++ b/test/fixedbugs/issue63333.go @@ -0,0 +1,15 @@ +// errorcheck -goexperiment fieldtrack + +// Copyright 2023 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 + +func f(interface{ m() }) {} +func g() { f(new(T)) } // ERROR "m method is marked 'nointerface'" + +type T struct{} + +//go:nointerface +func (*T) m() {}