diff --git a/go/types/expr.go b/go/types/expr.go index a414d32f..b8b6b667 100644 --- a/go/types/expr.go +++ b/go/types/expr.go @@ -1031,6 +1031,11 @@ func (check *checker) callExpr(x *operand) { // cycleOk indicates whether it is ok for a type expression to refer to itself. // func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type, iota int, cycleOk bool) { + // make sure x has a valid state for deferred functions in case of bailout + // (was issue 5770) + x.mode = invalid + x.typ = Typ[Invalid] + if trace { c := "" if cycleOk { diff --git a/go/types/issues_test.go b/go/types/issues_test.go new file mode 100644 index 00000000..21682358 --- /dev/null +++ b/go/types/issues_test.go @@ -0,0 +1,28 @@ +// Copyright 2013 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. + +// This file implements tests for various issues. + +package types + +import ( + "go/parser" + "strings" + "testing" +) + +func TestIssue5770(t *testing.T) { + src := `package p; type S struct{T}` + f, err := parser.ParseFile(fset, "", src, 0) + if err != nil { + t.Error(err) + return + } + + _, err = Check(f.Name.Name, fset, f) // do not crash + want := "undeclared name: T" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("got: %v; want: %s", err, want) + } +}