Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/types: dot imports might cause errors where (types.Error).Pos is not part of the (types.Error).Fset #71272

Open
mateusz834 opened this issue Jan 14, 2025 · 2 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Comments

@mateusz834
Copy link
Member

Reproducer:

package main

import (
	"fmt"
	"go/ast"
	"go/importer"
	"go/parser"
	"go/token"
	"go/types"
)

func main() {
	fmt.Println(run())
}

const src = `package main

import . "net/http"

type Request struct{}
`

func run() error {
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, "test.go", src, parser.SkipObjectResolution)
	if err != nil {
		return err
	}

	cfg := types.Config{
		Importer: importer.Default(),
		Error: func(err error) {
			e := err.(types.Error)
			fmt.Println(e.Msg, e.Pos, e.Fset.Position(e.Pos))
		},
	}

	cfg.Check("test", fset, []*ast.File{f}, nil)

	return nil
}
$ go run .
Request already declared through dot-import of package http ("net/http") 41 test.go:5:6
        other declaration of Request 2883740 -
"net/http" imported and not used 22 test.go:3:8
<nil>

Note the second error other declaration of Request 2883740 -, which tries to reference the file in the net/http package.

CC @adonovan @griesemer @findleyr

@mateusz834 mateusz834 added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 14, 2025
@mateusz834
Copy link
Member Author

This happens because of the default FileSet here:

// For calls [ForCompiler] with a new FileSet.
//
// Deprecated: Use [ForCompiler], which populates a FileSet
// with the positions of objects created by the importer.
func For(compiler string, lookup Lookup) types.Importer {
return ForCompiler(token.NewFileSet(), compiler, lookup)
}
// Default returns an Importer for the compiler that built the running binary.
// If available, the result implements [types.ImporterFrom].
func Default() types.Importer {
return For(runtime.Compiler, nil)
}

It can be fixed by using the importer.ForCompiler, with the same fileset as provided to the type checker.

Importer: importer.ForCompiler(fset, runtime.Compiler, nil),

Also (not tested) but i guess it cannot happen with go/pacakges, since it uses one fileset for all operations.

@findleyr
Copy link
Member

Thanks. Superficially this seems like it may also be a source of gopls bug reports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

2 participants