<p dir="auto"><strong>1 What version of Go are you using (go version)?</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ go version
go version go1.6 linux/amd64"><pre class="notranslate"><code class="notranslate">$ go version
go version go1.6 linux/amd64
</code></pre></div>
<p dir="auto"><strong>2 What operating system and processor architecture are you using?</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ cat /etc/issue
Ubuntu 15.10 \n \l

$ lscpu
Architecture:          x86_64
..."><pre class="notranslate"><code class="notranslate">$ cat /etc/issue
Ubuntu 15.10 \n \l

$ lscpu
Architecture:          x86_64
...
</code></pre></div>
<p dir="auto"><strong>3 What did you do?</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ tree $GOPATH/src
├── a
│   ├── a.go
│   └── vendor
│       └── b
│           └── b.go
└── build
    └── main.go

$ cat $GOPATH/src/build/main.go"><pre class="notranslate"><code class="notranslate">$ tree $GOPATH/src
├── a
│   ├── a.go
│   └── vendor
│       └── b
│           └── b.go
└── build
    └── main.go

$ cat $GOPATH/src/build/main.go
</code></pre></div>
<div class="highlight highlight-source-go notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="package main

    import (
        &quot;go/ast&quot;
        &quot;go/build&quot;
        &quot;go/importer&quot;
        &quot;go/parser&quot;
        &quot;go/token&quot;
        &quot;go/types&quot;
        &quot;os&quot;
        &quot;path&quot;
    )

    func panicOnErr(err error) {
        if err != nil {
            panic(err.Error())
        }
    }

    func main() {
        gopath := os.Getenv(&quot;GOPATH&quot;)   
        dir := path.Join(gopath, &quot;src&quot;, &quot;a&quot;)

        //  println(&quot;dir: &quot; + dir)
        fset := token.NewFileSet()
        buildPkg, err := build.ImportDir(dir, build.ImportMode(0))

        panicOnErr(err)

        astFiles := []*ast.File{}

        for _, filename := range buildPkg.GoFiles {
            file, err := parser.ParseFile(fset, path.Join(dir, filename), nil, parser.AllErrors)
            panicOnErr(err)
            astFiles = append(astFiles, file)
        }

        for _, filename := range buildPkg.CgoFiles {
            file, err := parser.ParseFile(fset, path.Join(dir, filename), nil, parser.AllErrors)
            panicOnErr(err)
            astFiles = append(astFiles, file)
        }

        typesInfo := &amp;types.Info{
            Types: make(map[ast.Expr]types.TypeAndValue),
            Defs:  make(map[*ast.Ident]types.Object),
            Uses:  make(map[*ast.Ident]types.Object),
        }

        var conf types.Config
        conf.Importer = importer.Default()
        conf.IgnoreFuncBodies = true
        typesPkg, err := conf.Check(buildPkg.Name, fset, astFiles, typesInfo)

        panicOnErr(err)

        _ = typesPkg
    }"><pre class="notranslate"><span class="pl-k">package</span> main

    <span class="pl-k">import</span> (
        <span class="pl-s">"go/ast"</span>
        <span class="pl-s">"go/build"</span>
        <span class="pl-s">"go/importer"</span>
        <span class="pl-s">"go/parser"</span>
        <span class="pl-s">"go/token"</span>
        <span class="pl-s">"go/types"</span>
        <span class="pl-s">"os"</span>
        <span class="pl-s">"path"</span>
    )

    <span class="pl-k">func</span> <span class="pl-en">panicOnErr</span>(<span class="pl-s1">err</span> <span class="pl-smi">error</span>) {
        <span class="pl-k">if</span> <span class="pl-s1">err</span> <span class="pl-c1">!=</span> <span class="pl-c1">nil</span> {
            <span class="pl-en">panic</span>(<span class="pl-s1">err</span>.<span class="pl-en">Error</span>())
        }
    }

    <span class="pl-k">func</span> <span class="pl-en">main</span>() {
        <span class="pl-s1">gopath</span> <span class="pl-c1">:=</span> <span class="pl-s1">os</span>.<span class="pl-en">Getenv</span>(<span class="pl-s">"GOPATH"</span>)   
        <span class="pl-s1">dir</span> <span class="pl-c1">:=</span> <span class="pl-s1">path</span>.<span class="pl-en">Join</span>(<span class="pl-s1">gopath</span>, <span class="pl-s">"src"</span>, <span class="pl-s">"a"</span>)

        <span class="pl-c">//  println("dir: " + dir)</span>
        <span class="pl-s1">fset</span> <span class="pl-c1">:=</span> <span class="pl-s1">token</span>.<span class="pl-en">NewFileSet</span>()
        <span class="pl-s1">buildPkg</span>, <span class="pl-s1">err</span> <span class="pl-c1">:=</span> <span class="pl-s1">build</span>.<span class="pl-en">ImportDir</span>(<span class="pl-s1">dir</span>, <span class="pl-s1">build</span>.<span class="pl-en">ImportMode</span>(<span class="pl-c1">0</span>))

        <span class="pl-en">panicOnErr</span>(<span class="pl-s1">err</span>)

        <span class="pl-s1">astFiles</span> <span class="pl-c1">:=</span> []<span class="pl-c1">*</span>ast.<span class="pl-smi">File</span>{}

        <span class="pl-k">for</span> <span class="pl-s1">_</span>, <span class="pl-s1">filename</span> <span class="pl-c1">:=</span> <span class="pl-k">range</span> <span class="pl-s1">buildPkg</span>.<span class="pl-c1">GoFiles</span> {
            <span class="pl-s1">file</span>, <span class="pl-s1">err</span> <span class="pl-c1">:=</span> <span class="pl-s1">parser</span>.<span class="pl-en">ParseFile</span>(<span class="pl-s1">fset</span>, <span class="pl-s1">path</span>.<span class="pl-en">Join</span>(<span class="pl-s1">dir</span>, <span class="pl-s1">filename</span>), <span class="pl-c1">nil</span>, <span class="pl-s1">parser</span>.<span class="pl-c1">AllErrors</span>)
            <span class="pl-en">panicOnErr</span>(<span class="pl-s1">err</span>)
            <span class="pl-s1">astFiles</span> <span class="pl-c1">=</span> <span class="pl-en">append</span>(<span class="pl-s1">astFiles</span>, <span class="pl-s1">file</span>)
        }

        <span class="pl-k">for</span> <span class="pl-s1">_</span>, <span class="pl-s1">filename</span> <span class="pl-c1">:=</span> <span class="pl-k">range</span> <span class="pl-s1">buildPkg</span>.<span class="pl-c1">CgoFiles</span> {
            <span class="pl-s1">file</span>, <span class="pl-s1">err</span> <span class="pl-c1">:=</span> <span class="pl-s1">parser</span>.<span class="pl-en">ParseFile</span>(<span class="pl-s1">fset</span>, <span class="pl-s1">path</span>.<span class="pl-en">Join</span>(<span class="pl-s1">dir</span>, <span class="pl-s1">filename</span>), <span class="pl-c1">nil</span>, <span class="pl-s1">parser</span>.<span class="pl-c1">AllErrors</span>)
            <span class="pl-en">panicOnErr</span>(<span class="pl-s1">err</span>)
            <span class="pl-s1">astFiles</span> <span class="pl-c1">=</span> <span class="pl-en">append</span>(<span class="pl-s1">astFiles</span>, <span class="pl-s1">file</span>)
        }

        <span class="pl-s1">typesInfo</span> <span class="pl-c1">:=</span> <span class="pl-c1">&amp;</span>types.<span class="pl-smi">Info</span>{
            <span class="pl-c1">Types</span>: <span class="pl-en">make</span>(<span class="pl-k">map</span>[ast.<span class="pl-smi">Expr</span>]types.<span class="pl-smi">TypeAndValue</span>),
            <span class="pl-c1">Defs</span>:  <span class="pl-en">make</span>(<span class="pl-k">map</span>[<span class="pl-c1">*</span>ast.<span class="pl-smi">Ident</span>]types.<span class="pl-smi">Object</span>),
            <span class="pl-c1">Uses</span>:  <span class="pl-en">make</span>(<span class="pl-k">map</span>[<span class="pl-c1">*</span>ast.<span class="pl-smi">Ident</span>]types.<span class="pl-smi">Object</span>),
        }

        <span class="pl-k">var</span> <span class="pl-s1">conf</span> types.<span class="pl-smi">Config</span>
        <span class="pl-s1">conf</span>.<span class="pl-c1">Importer</span> <span class="pl-c1">=</span> <span class="pl-s1">importer</span>.<span class="pl-en">Default</span>()
        <span class="pl-s1">conf</span>.<span class="pl-c1">IgnoreFuncBodies</span> <span class="pl-c1">=</span> <span class="pl-c1">true</span>
        <span class="pl-s1">typesPkg</span>, <span class="pl-s1">err</span> <span class="pl-c1">:=</span> <span class="pl-s1">conf</span>.<span class="pl-en">Check</span>(<span class="pl-s1">buildPkg</span>.<span class="pl-c1">Name</span>, <span class="pl-s1">fset</span>, <span class="pl-s1">astFiles</span>, <span class="pl-s1">typesInfo</span>)

        <span class="pl-en">panicOnErr</span>(<span class="pl-s1">err</span>)

        <span class="pl-s1">_</span> <span class="pl-c1">=</span> <span class="pl-s1">typesPkg</span>
    }</pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ cat $GOPATH/src/a/a.go"><pre class="notranslate"><code class="notranslate">$ cat $GOPATH/src/a/a.go
</code></pre></div>
<div class="highlight highlight-source-go notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    package a

    import &quot;b&quot;

    var foo = b.Foo"><pre class="notranslate">    <span class="pl-k">package</span> a

    <span class="pl-k">import</span> <span class="pl-s">"b"</span>

    <span class="pl-k">var</span> <span class="pl-s1">foo</span> <span class="pl-c1">=</span> <span class="pl-s1">b</span>.<span class="pl-c1">Foo</span></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ cat $GOPATH/src/a/vendor/b/b.go"><pre class="notranslate"><code class="notranslate">$ cat $GOPATH/src/a/vendor/b/b.go
</code></pre></div>
<div class="highlight highlight-source-go notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    package b

    var Foo = &quot;bar&quot;"><pre class="notranslate">    <span class="pl-k">package</span> b

    <span class="pl-k">var</span> <span class="pl-s1">Foo</span> <span class="pl-c1">=</span> <span class="pl-s">"bar"</span></pre></div>
<p dir="auto"><strong>4 What did you expect to see?</strong></p>
<p dir="auto">Nothing (that's OK)</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ go run build/main.go"><pre class="notranslate"><code class="notranslate">$ go run build/main.go
</code></pre></div>
<p dir="auto"><strong>5 What did you see instead?</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ go env &amp;&amp; go version &amp;&amp; go run $GOPATH/src/build/main.go 
GOARCH=&quot;amd64&quot;
GOBIN=&quot;&quot;
GOEXE=&quot;&quot;
GOHOSTARCH=&quot;amd64&quot;
GOHOSTOS=&quot;linux&quot;
GOOS=&quot;linux&quot;
GOPATH=&quot;/home/benny/Entwicklung/testdebug/gopath&quot;
GORACE=&quot;&quot;
GOROOT=&quot;/home/benny/bin/go&quot;
GOTOOLDIR=&quot;/home/benny/bin/go/pkg/tool/linux_amd64&quot;
GO15VENDOREXPERIMENT=&quot;1&quot;
CC=&quot;gcc&quot;
GOGCCFLAGS=&quot;-fPIC -m64 -pthread -fmessage-length=0&quot;
CXX=&quot;g++&quot;
CGO_ENABLED=&quot;1&quot;
go version go1.6 linux/amd64
panic: a/a.go:3:8: could not import b (can't find import: a/vendor/b)

goroutine 1 [running]:
panic(0x653760, 0xc82000ade0)
    go/src/runtime/panic.go:464 +0x3e6
main.panicOnErr(0x7fb0a76aac58, 0xc82000fe00)
    build/main.go:16 +0x7e
main.main()
    build/main.go:56 +0x8bd
exit status 2"><pre class="notranslate"><code class="notranslate">$ go env &amp;&amp; go version &amp;&amp; go run $GOPATH/src/build/main.go 
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/benny/Entwicklung/testdebug/gopath"
GORACE=""
GOROOT="/home/benny/bin/go"
GOTOOLDIR="/home/benny/bin/go/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT="1"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"
go version go1.6 linux/amd64
panic: a/a.go:3:8: could not import b (can't find import: a/vendor/b)

goroutine 1 [running]:
panic(0x653760, 0xc82000ade0)
    go/src/runtime/panic.go:464 +0x3e6
main.panicOnErr(0x7fb0a76aac58, 0xc82000fe00)
    build/main.go:16 +0x7e
main.main()
    build/main.go:56 +0x8bd
exit status 2
</code></pre></div>
<p dir="auto"><strong>Further information</strong></p>
<p dir="auto">When installing the vendor package</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ go install $GOPATH/src/a/vendor/b "><pre class="notranslate"><code class="notranslate">$ go install $GOPATH/src/a/vendor/b 
</code></pre></div>
<p dir="auto">before running</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ go run $GOPATH/src/build/main.go"><pre class="notranslate"><code class="notranslate">$ go run $GOPATH/src/build/main.go
</code></pre></div>
<p dir="auto">It runs fine as expected. After removing the build</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ rm $GOPATH/pkg/linux_amd64/a/vendor/b.a"><pre class="notranslate"><code class="notranslate">$ rm $GOPATH/pkg/linux_amd64/a/vendor/b.a
</code></pre></div>
<p dir="auto">It complains again</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ go run $GOPATH/src/build/main.go
panic: a/a.go:3:8: could not import b (can't find import: a/vendor/b)

goroutine 1 [running]:
panic(0x653760, 0xc82000ade0)
    go/src/runtime/panic.go:464 +0x3e6
main.panicOnErr(0x7fb0a76aac58, 0xc82000fe00)
    build/main.go:16 +0x7e
main.main()
    build/main.go:56 +0x8bd
exit status 2"><pre class="notranslate"><code class="notranslate">$ go run $GOPATH/src/build/main.go
panic: a/a.go:3:8: could not import b (can't find import: a/vendor/b)

goroutine 1 [running]:
panic(0x653760, 0xc82000ade0)
    go/src/runtime/panic.go:464 +0x3e6
main.panicOnErr(0x7fb0a76aac58, 0xc82000fe00)
    build/main.go:16 +0x7e
main.main()
    build/main.go:56 +0x8bd
exit status 2
</code></pre></div>
<p dir="auto">Probably related to <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="131174883" data-permission-text="Title is private" data-url="https://github.com/golang/go/issues/14215" data-hovercard-type="issue" data-hovercard-url="/golang/go/issues/14215/hovercard" href="https://github.com/golang/go/issues/14215">#14215</a></p>
<p dir="auto">It is common to use go/types is as part of a go generate command<br>
or other command line tool to introspect a Go package.</p>
<p dir="auto">The go tool goes to some lengths to ensure that whenever<br>
you operate on a package, it builds the source for that<br>
package into object form before using it, so you don't<br>
end up using symbol information that's out of date with respect<br>
to the source.</p>
<p dir="auto">When using go/types from a command line tool, you<br>
don't have that luxury, and it's not necessarily appropriate<br>
to call "go install" automatically.</p>
<p dir="auto">I believe that a better way would be for the default<br>
importer to use the object file data only if it's newer<br>
than the source files, otherwise fall back to using the<br>
source directly. Or at least it would be nice to have<br>
that option, so that it's easy to make go generate<br>
utilities operate on the up to date code.</p>
<p dir="auto">I hope this could be considered before Go 1.5 as<br>
we won't be able to change this behaviour after then.</p>