From 4e77fc9436ab8021246312ed94bb1e625688ac20 Mon Sep 17 00:00:00 2001 From: Ethan Reesor Date: Tue, 26 Apr 2022 04:04:13 -0500 Subject: [PATCH] interp: delete incomplete type on pkg import When a package is imported, it creates a symbol with a name like "errors/_.go". If a statement such as x := errors.New(...) is executed before import "errors", it creates an incomplete type symbol with a name like "errors". Importing the package after the incomplete type symbol has been created does not fix the compile issue because the incomplete type still exists. To fix this, this PR deletes the incomplete type symbol, if one exists. Closes #1388. --- interp/gta.go | 6 ++++++ interp/interp_eval_test.go | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/interp/gta.go b/interp/gta.go index 05b5ac203..d75f0b2e4 100644 --- a/interp/gta.go +++ b/interp/gta.go @@ -217,6 +217,12 @@ func (interp *Interpreter) gta(root *node, rpath, importPath, pkgName string) ([ if name == "" { name = interp.pkgNames[ipath] } + + // If an incomplete type exists, delete it + if sym, exists := sc.sym[name]; exists && sym.kind == typeSym && sym.typ.incomplete { + delete(sc.sym, name) + } + // Imports of a same package are all mapped in the same scope, so we cannot just // map them by their names, otherwise we could have collisions from same-name // imports in different source files of the same package. Therefore, we suffix diff --git a/interp/interp_eval_test.go b/interp/interp_eval_test.go index d7e756630..7cde405ad 100644 --- a/interp/interp_eval_test.go +++ b/interp/interp_eval_test.go @@ -1751,6 +1751,29 @@ func TestRestrictedEnv(t *testing.T) { } } +func TestIssue1388(t *testing.T) { + i := interp.New(interp.Options{Env: []string{"foo=bar"}}) + err := i.Use(stdlib.Symbols) + if err != nil { + t.Fatal(err) + } + + _, err = i.Eval(`x := errors.New("")`) + if err == nil { + t.Fatal("Expected an error") + } + + _, err = i.Eval(`import "errors"`) + if err != nil { + t.Fatal(err) + } + + _, err = i.Eval(`x := errors.New("")`) + if err != nil { + t.Fatal(err) + } +} + func TestIssue1383(t *testing.T) { const src = ` package main