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/importer: default importer should not use out of date type information #11415

Closed
rogpeppe opened this issue Jun 26, 2015 · 15 comments
Closed
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@rogpeppe
Copy link
Contributor

It is common to use go/types is as part of a go generate command
or other command line tool to introspect a Go package.

The go tool goes to some lengths to ensure that whenever
you operate on a package, it builds the source for that
package into object form before using it, so you don't
end up using symbol information that's out of date with respect
to the source.

When using go/types from a command line tool, you
don't have that luxury, and it's not necessarily appropriate
to call "go install" automatically.

I believe that a better way would be for the default
importer to use the object file data only if it's newer
than the source files, otherwise fall back to using the
source directly. Or at least it would be nice to have
that option, so that it's easy to make go generate
utilities operate on the up to date code.

I hope this could be considered before Go 1.5 as
we won't be able to change this behaviour after then.

@adonovan
Copy link
Member

The go/types package takes no opinion on issues like this, by design. It's simply a function from ASTs to type information, and it makes upcalls into the client application if it needs to import type information for dependencies.

Many applications use the gcimporter package to read type information from compiled object files, though as you point out, there's no guarantee that those files are even remotely recent. This seems like a bad default to me.

Many other applications use the golang.org/x/tools/go/loader package, which loads the entire program from source code, and parses and type-checks it, so the correct result is guaranteed. It's slower of course, but still quite fast: to load golang.org/x/tools/cmd/oracle (130KLoC) takes about 400ms.

If you care about staleness, and you should then, then use go/loader. A hybrid mechanism that uses gcimporter if fresh and source if not seems tricky to get right. I recently dropped support for hybrid loading from go/loader for reasons of complexity, and it didn't even use a staleness check.

This is one of many things that we need (and plan) to document in the go/types API for Go 1.5.

@mvdan
Copy link
Member

mvdan commented Dec 15, 2015

This is one of many things that we need (and plan) to document in the go/types API for Go 1.5.

@adonovan couldn't agree more. I spent two days tracking an import bug (mentioned just above) that was just this. Could have saved me quite some time if either go/types or go/importer mentioned this common assumption/mistake.

@willfaught
Copy link
Contributor

Will the fix for this make go/importer compatible with how the go tool treats vendored types as discussed in #14496?

@griesemer
Copy link
Contributor

@willfaught #14496 was closed as a duplicate of this issue - so yes.

@gopherbot
Copy link

CL https://golang.org/cl/36992 mentions this issue.

gopherbot pushed a commit to golang/tools that referenced this issue Feb 17, 2017
As noted by griesemer in golang/go#18799, this doesn't address the issues
raised in golang/go#11415 because when checking an xtest package the
corresponding package is assumed to have been installed. This
however is similar to the assumptions made by go vet (raised
as an issue in golang/go#16086). So whilst not perfect, it will probably
suffice until golang/go#11415 is resolved.

Fixes golang/go#18799

Change-Id: I1ea005c402e5d6f5abddda68fee6386b0531dfba
Reviewed-on: https://go-review.googlesource.com/36992
Reviewed-by: Robert Griesemer <gri@golang.org>
@gopherbot
Copy link

CL https://golang.org/cl/37393 mentions this issue.

@gopherbot
Copy link

CL https://golang.org/cl/37405 mentions this issue.

gopherbot pushed a commit that referenced this issue Feb 27, 2017
For #11415.

Change-Id: I87a8f534ab9dfd5022422457ea637b342c057d77
Reviewed-on: https://go-review.googlesource.com/37393
Reviewed-by: Alan Donovan <adonovan@google.com>
gopherbot pushed a commit that referenced this issue Feb 27, 2017
For #11415.

Change-Id: I5da39dad059113cfc4276152390aa4925bd18862
Reviewed-on: https://go-review.googlesource.com/37405
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
@griesemer
Copy link
Contributor

The go/importer package now supports importing from "source" (use importer.For("source", nil) rather than importer.Default()). See the above-mentioned CLs for details.

The original issue description asks for a more automatic approach that selects between installed packages and/or source depending on whichever is newer. Using source always will most often be the correct (and least surprising) approach.

See issue #19337 for problems related to making a mixed-mode automatic approach feasible.

Considering this issue resolved at this time.

@willfaught
Copy link
Contributor

Is it planned for gotype to use this new importer?

@mvdan
Copy link
Member

mvdan commented Mar 3, 2017

@willfaught if you mean x/tools/cmd/gotype, it's gone: golang/tools@f5a6ee1

@griesemer
Copy link
Contributor

griesemer commented Mar 3, 2017 via email

@willfaught
Copy link
Contributor

@mvdan Didn't know it had been removed. GTK.

@griesemer Doesn't that break a plain go build command in src/go/types, since its package is main? How does that work?

@griesemer
Copy link
Contributor

@willfaught The file has a // +build ignore line.

@willfaught
Copy link
Contributor

willfaught commented Mar 5, 2017 via email

@griesemer
Copy link
Contributor

griesemer commented Mar 6, 2017

@willfaught It's not "archived". I for one (and others) use it frequently. It's just not yet become a "regular" command (in the std library).

@golang golang locked and limited conversation to collaborators Mar 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

10 participants