all: merge master into release-branch.go1.6

Change-Id: I10a3abc28028e35c5d92d1bd33ac64fe0825eae7
diff --git a/doc/go1.6.html b/doc/go1.6.html
index 46a8f65..b4a3900 100644
--- a/doc/go1.6.html
+++ b/doc/go1.6.html
@@ -464,20 +464,8 @@
 combined with allowing redefinition of named templates,
 provides a simple way to define pieces of a template that
 can be replaced in different instantiations.
-For example, the template
-</p>
-
-<pre>
-&lt;title&gt;{{"{{"}}block "title"}}Page Title{{"{{"}}end}}&lt;/title&gt;
-&lt;body&gt;
-&lt;h1&gt;{{"{{"}}template "title"}}&lt;/h1&gt;
-{{"{{"}}block "page"}}Main text{{"{{"}}end}}
-</pre>
-
-<p>
-defines the basic formatting of a web page. A program can then
-overlay that template with new definitions for the <code>"title"</code>
-and <code>"page"</code> blocks to reuse the formatting for another page.
+There is <a href="/pkg/text/template/#example_Template_block">an example</a>
+in the <code>text/template</code> package that demonstrates this new feature.
 </p>
 
 <h3 id="minor_library_changes">Minor changes to the library</h3>
@@ -752,13 +740,13 @@
 <code>Expect:</code> <code>100-continue</code> header (see
 <a href="/pkg/net/http/#Transport"><code>Transport.ExpectContinueTimeout</code></a>).
 Fourth, there are
-<a href="/pkg/net/http/#pkg-constants">five new error codes</a> from RFC 6585:
+<a href="/pkg/net/http/#pkg-constants">five new error codes</a>:
 <code>StatusPreconditionRequired</code> (428),
 <code>StatusTooManyRequests</code> (429),
-<code>StatusRequestHeaderFieldsTooLarge</code> (431),
-<code>StatusUnavailableForLegalReasons</code> (451)),
-and
-<code>StatusNetworkAuthenticationRequired</code> (511).
+<code>StatusRequestHeaderFieldsTooLarge</code> (431), and
+<code>StatusNetworkAuthenticationRequired</code> (511) from RFC 6585,
+as well as the recently-approved
+<code>StatusUnavailableForLegalReasons</code> (451).
 Fifth, the implementation and documentation of
 <a href="/pkg/net/http/#CloseNotifier"><code>CloseNotifier</code></a>
 has been substantially changed.
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index 282e855..054cf73 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -2501,6 +2501,24 @@
 		ifacedcl(meth)
 		return meth
 
+	case '@', '?':
+		// newname indcl
+		// We arrive here when parsing an interface type declared inside
+		// an exported and inlineable function and the interface declares
+		// unexported methods (which are then package-qualified).
+		//
+		// Since the compiler always flattens embedded interfaces, we
+		// will never see an embedded package-qualified interface in export
+		// data; i.e., when we reach here we know it must be a method.
+		//
+		// See also issue 14164.
+		mname := newname(p.sym())
+		sig := p.indcl()
+
+		meth := Nod(ODCLFIELD, mname, sig)
+		ifacedcl(meth)
+		return meth
+
 	case '(':
 		p.next()
 		pname := p.packname(nil)
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index a901ca8..0136ba4 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -1621,7 +1621,7 @@
 }
 
 // Issue 4568.
-func TestSymlinksDoNotConfuseGoList(t *testing.T) {
+func TestSymlinksList(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9", "windows":
 		t.Skipf("skipping symlink test on %s", runtime.GOOS)
@@ -1640,6 +1640,58 @@
 	}
 }
 
+// Issue 14054.
+func TestSymlinksVendor(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("skipping symlink test on %s", runtime.GOOS)
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.tempDir("gopath/src/dir1/vendor/v")
+	tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `v`\nfunc main(){}")
+	tg.tempFile("gopath/src/dir1/vendor/v/v.go", "package v")
+	tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1")))
+	tg.setenv("GOPATH", tg.path("gopath"))
+	tg.cd(tg.path("symdir1"))
+	tg.run("list", "-f", "{{.Root}}", ".")
+	if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") {
+		t.Error("list confused by symlinks")
+	}
+
+	// All of these should succeed, not die in vendor-handling code.
+	tg.run("run", "p.go")
+	tg.run("build")
+	tg.run("install")
+}
+
+func TestSymlinksInternal(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("skipping symlink test on %s", runtime.GOOS)
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempDir("gopath/src/dir1/internal/v")
+	tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `dir1/internal/v`\nfunc main(){}")
+	tg.tempFile("gopath/src/dir1/internal/v/v.go", "package v")
+	tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1")))
+	tg.setenv("GOPATH", tg.path("gopath"))
+	tg.cd(tg.path("symdir1"))
+	tg.run("list", "-f", "{{.Root}}", ".")
+	if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") {
+		t.Error("list confused by symlinks")
+	}
+
+	// All of these should succeed, not die in internal-handling code.
+	tg.run("run", "p.go")
+	tg.run("build")
+	tg.run("install")
+}
+
 // Issue 4515.
 func TestInstallWithTags(t *testing.T) {
 	tg := testgo(t)
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index c8697ff..d384594 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -524,6 +524,15 @@
 	}
 }
 
+// expandPath returns the symlink-expanded form of path.
+func expandPath(p string) string {
+	x, err := filepath.EvalSymlinks(p)
+	if err == nil {
+		return x
+	}
+	return p
+}
+
 // treeCanMatchPattern(pattern)(name) reports whether
 // name or children of name can possibly match pattern.
 // Pattern is the same limited glob accepted by matchPattern.
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index 112f820..95a06ff 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -415,11 +415,18 @@
 	if parent == nil || parent.Root == "" || !go15VendorExperiment {
 		return path
 	}
+
 	dir := filepath.Clean(parent.Dir)
 	root := filepath.Join(parent.Root, "src")
+	if !hasFilePathPrefix(dir, root) {
+		// Look for symlinks before reporting error.
+		dir = expandPath(dir)
+		root = expandPath(root)
+	}
 	if !hasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator {
 		fatalf("invalid vendoredImportPath: dir=%q root=%q separator=%q", dir, root, string(filepath.Separator))
 	}
+
 	vpath := "vendor/" + path
 	for i := len(dir); i >= len(root); i-- {
 		if i < len(dir) && dir[i] != filepath.Separator {
@@ -533,6 +540,13 @@
 		return p
 	}
 
+	// Look for symlinks before reporting error.
+	srcDir = expandPath(srcDir)
+	parent = expandPath(parent)
+	if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
+		return p
+	}
+
 	// Internal is present, and srcDir is outside parent's tree. Not allowed.
 	perr := *p
 	perr.Error = &PackageError{
@@ -630,6 +644,13 @@
 		return p
 	}
 
+	// Look for symlinks before reporting error.
+	srcDir = expandPath(srcDir)
+	parent = expandPath(parent)
+	if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
+		return p
+	}
+
 	// Vendor is present, and srcDir is outside parent's tree. Not allowed.
 	perr := *p
 	perr.Error = &PackageError{
diff --git a/src/cmd/vet/print.go b/src/cmd/vet/print.go
index 5436c5b..a16e864 100644
--- a/src/cmd/vet/print.go
+++ b/src/cmd/vet/print.go
@@ -445,12 +445,12 @@
 		return false
 	}
 	arg := call.Args[argNum]
+	if f.isFunctionValue(arg) && state.verb != 'p' && state.verb != 'T' {
+		f.Badf(call.Pos(), "arg %s in printf call is a function value, not a function call", f.gofmt(arg))
+		return false
+	}
 	if !f.matchArgType(v.typ, nil, arg) {
 		typeString := ""
-		if f.isFunctionValue(arg) {
-			f.Badf(call.Pos(), "arg %s in printf call is a function value, not a function call", f.gofmt(arg))
-			return false
-		}
 		if typ := f.pkg.types[arg].Type; typ != nil {
 			typeString = typ.String()
 		}
diff --git a/src/cmd/vet/testdata/print.go b/src/cmd/vet/testdata/print.go
index beeb642..c5faa36 100644
--- a/src/cmd/vet/testdata/print.go
+++ b/src/cmd/vet/testdata/print.go
@@ -197,7 +197,10 @@
 	et5.error() // ok, not an error method.
 	// Can't print a function.
 	Printf("%d", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
+	Printf("%v", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
 	Println(someFunction)      // ERROR "arg someFunction in Println call is a function value, not a function call"
+	Printf("%p", someFunction) // ok: maybe someone wants to see the pointer
+	Printf("%T", someFunction) // ok: maybe someone wants to see the type
 	// Bug: used to recur forever.
 	Printf("%p %x", recursiveStructV, recursiveStructV.next)
 	Printf("%p %x", recursiveStruct1V, recursiveStruct1V.next)
diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go
index 9b581e7..fbaa805 100644
--- a/src/net/http/clientserver_test.go
+++ b/src/net/http/clientserver_test.go
@@ -1001,13 +1001,17 @@
 }
 
 // tests that Transport doesn't retain a pointer to the provided request.
-func TestTransportGCRequest_h1(t *testing.T) { testTransportGCRequest(t, h1Mode) }
-func TestTransportGCRequest_h2(t *testing.T) { testTransportGCRequest(t, h2Mode) }
-func testTransportGCRequest(t *testing.T, h2 bool) {
+func TestTransportGCRequest_Body_h1(t *testing.T)   { testTransportGCRequest(t, h1Mode, true) }
+func TestTransportGCRequest_Body_h2(t *testing.T)   { testTransportGCRequest(t, h2Mode, true) }
+func TestTransportGCRequest_NoBody_h1(t *testing.T) { testTransportGCRequest(t, h1Mode, false) }
+func TestTransportGCRequest_NoBody_h2(t *testing.T) { testTransportGCRequest(t, h2Mode, false) }
+func testTransportGCRequest(t *testing.T, h2, body bool) {
 	defer afterTest(t)
 	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
 		ioutil.ReadAll(r.Body)
-		io.WriteString(w, "Hello.")
+		if body {
+			io.WriteString(w, "Hello.")
+		}
 	}))
 	defer cst.close()
 
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index e723629..11f33cf 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -2851,8 +2851,6 @@
 	}
 }
 
-var http2uintptrType = reflect.TypeOf(uintptr(0))
-
 // errno returns v's underlying uintptr, else 0.
 //
 // TODO: remove this helper function once http2 can use build
@@ -4220,7 +4218,9 @@
 
 		return
 	}
-	rws.trailers = append(rws.trailers, k)
+	if !http2strSliceContains(rws.trailers, k) {
+		rws.trailers = append(rws.trailers, k)
+	}
 }
 
 // writeChunk writes chunks from the bufio.Writer. But because
@@ -4288,6 +4288,10 @@
 		return 0, nil
 	}
 
+	if rws.handlerDone {
+		rws.promoteUndeclaredTrailers()
+	}
+
 	endStream := rws.handlerDone && !rws.hasTrailers()
 	if len(p) > 0 || endStream {
 
@@ -4308,6 +4312,53 @@
 	return len(p), nil
 }
 
+// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
+// that, if present, signals that the map entry is actually for
+// the response trailers, and not the response headers. The prefix
+// is stripped after the ServeHTTP call finishes and the values are
+// sent in the trailers.
+//
+// This mechanism is intended only for trailers that are not known
+// prior to the headers being written. If the set of trailers is fixed
+// or known before the header is written, the normal Go trailers mechanism
+// is preferred:
+//    https://golang.org/pkg/net/http/#ResponseWriter
+//    https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
+const http2TrailerPrefix = "Trailer:"
+
+// promoteUndeclaredTrailers permits http.Handlers to set trailers
+// after the header has already been flushed. Because the Go
+// ResponseWriter interface has no way to set Trailers (only the
+// Header), and because we didn't want to expand the ResponseWriter
+// interface, and because nobody used trailers, and because RFC 2616
+// says you SHOULD (but not must) predeclare any trailers in the
+// header, the official ResponseWriter rules said trailers in Go must
+// be predeclared, and then we reuse the same ResponseWriter.Header()
+// map to mean both Headers and Trailers.  When it's time to write the
+// Trailers, we pick out the fields of Headers that were declared as
+// trailers. That worked for a while, until we found the first major
+// user of Trailers in the wild: gRPC (using them only over http2),
+// and gRPC libraries permit setting trailers mid-stream without
+// predeclarnig them. So: change of plans. We still permit the old
+// way, but we also permit this hack: if a Header() key begins with
+// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
+// invalid token byte anyway, there is no ambiguity. (And it's already
+// filtered out) It's mildly hacky, but not terrible.
+//
+// This method runs after the Handler is done and promotes any Header
+// fields to be trailers.
+func (rws *http2responseWriterState) promoteUndeclaredTrailers() {
+	for k, vv := range rws.handlerHeader {
+		if !strings.HasPrefix(k, http2TrailerPrefix) {
+			continue
+		}
+		trailerKey := strings.TrimPrefix(k, http2TrailerPrefix)
+		rws.declareTrailer(trailerKey)
+		rws.handlerHeader[CanonicalHeaderKey(trailerKey)] = vv
+	}
+	sort.Strings(rws.trailers)
+}
+
 func (w *http2responseWriter) Flush() {
 	rws := w.rws
 	if rws == nil {
@@ -5611,10 +5662,10 @@
 			res.ContentLength = -1
 			res.Body = &http2gzipReader{body: res.Body}
 		}
+		rl.activeRes[cs.ID] = cs
 	}
 
 	cs.resTrailer = &res.Trailer
-	rl.activeRes[cs.ID] = cs
 	cs.resc <- http2resAndError{res: res}
 	rl.nextRes = nil
 	return nil
@@ -6258,8 +6309,16 @@
 	for _, k := range keys {
 		vv := h[k]
 		k = http2lowerHeader(k)
+		if !http2validHeaderFieldName(k) {
+
+			continue
+		}
 		isTE := k == "transfer-encoding"
 		for _, v := range vv {
+			if !http2validHeaderFieldValue(v) {
+
+				continue
+			}
 
 			if isTE && v != "trailers" {
 				continue
diff --git a/src/net/net_test.go b/src/net/net_test.go
index 6dcfc21..cd62b43 100644
--- a/src/net/net_test.go
+++ b/src/net/net_test.go
@@ -9,6 +9,7 @@
 	"os"
 	"runtime"
 	"testing"
+	"time"
 )
 
 func TestCloseRead(t *testing.T) {
@@ -209,6 +210,7 @@
 			defer os.Remove(ln.Addr().String())
 		}
 
+		dst := ln.Addr().String()
 		if err := ln.Close(); err != nil {
 			if perr := parseCloseError(err); perr != nil {
 				t.Error(perr)
@@ -222,9 +224,24 @@
 		}
 
 		if network == "tcp" {
-			cc, err := Dial("tcp", ln.Addr().String())
+			// We will have two TCP FSMs inside the
+			// kernel here. There's no guarantee that a
+			// signal comes from the far end FSM will be
+			// delivered immediately to the near end FSM,
+			// especially on the platforms that allow
+			// multiple consumer threads to pull pending
+			// established connections at the same time by
+			// enabling SO_REUSEPORT option such as Linux,
+			// DragonFly BSD. So we need to give some time
+			// quantum to the kernel.
+			//
+			// Note that net.inet.tcp.reuseport_ext=1 by
+			// default on DragonFly BSD.
+			time.Sleep(time.Millisecond)
+
+			cc, err := Dial("tcp", dst)
 			if err == nil {
-				t.Error("Dial to closed TCP listener succeeeded.")
+				t.Error("Dial to closed TCP listener succeeded.")
 				cc.Close()
 			}
 		}
@@ -272,6 +289,9 @@
 		}
 		addr := ln.Addr().String()
 		if err := ln.Close(); err != nil {
+			if perr := parseCloseError(err); perr != nil {
+				t.Error(perr)
+			}
 			t.Fatal(err)
 		}
 		ln, err = Listen("tcp", addr)
diff --git a/src/os/doc.go b/src/os/doc.go
index 389a8eb..869a28a 100644
--- a/src/os/doc.go
+++ b/src/os/doc.go
@@ -7,9 +7,13 @@
 import "time"
 
 // FindProcess looks for a running process by its pid.
+//
 // The Process it returns can be used to obtain information
 // about the underlying operating system process.
-func FindProcess(pid int) (p *Process, err error) {
+//
+// On Unix systems, FindProcess always succeeds and returns a Process
+// for the given pid, regardless of whether the process exists.
+func FindProcess(pid int) (*Process, error) {
 	return findProcess(pid)
 }
 
diff --git a/src/runtime/cgo_mmap.go b/src/runtime/cgo_mmap.go
index ef5501c..c0396bd 100644
--- a/src/runtime/cgo_mmap.go
+++ b/src/runtime/cgo_mmap.go
@@ -15,12 +15,19 @@
 //go:linkname _cgo_mmap _cgo_mmap
 var _cgo_mmap unsafe.Pointer
 
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (ret unsafe.Pointer) {
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer {
 	if _cgo_mmap != nil {
+		// Make ret a uintptr so that writing to it in the
+		// function literal does not trigger a write barrier.
+		// A write barrier here could break because of the way
+		// that mmap uses the same value both as a pointer and
+		// an errno value.
+		// TODO: Fix mmap to return two values.
+		var ret uintptr
 		systemstack(func() {
 			ret = callCgoMmap(addr, n, prot, flags, fd, off)
 		})
-		return
+		return unsafe.Pointer(ret)
 	}
 	return sysMmap(addr, n, prot, flags, fd, off)
 }
@@ -31,4 +38,4 @@
 // cgoMmap calls the mmap function in the runtime/cgo package on the
 // callCgoMmap calls the mmap function in the runtime/cgo package
 // using the GCC calling convention.  It is implemented in assembly.
-func callCgoMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
+func callCgoMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) uintptr
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 2bc3c92..d1f5088 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -1602,11 +1602,19 @@
 // Always runs without a P, so write barriers are not allowed.
 //go:nowritebarrier
 func handoffp(_p_ *p) {
+	// handoffp must start an M in any situation where
+	// findrunnable would return a G to run on _p_.
+
 	// if it has local work, start it straight away
 	if !runqempty(_p_) || sched.runqsize != 0 {
 		startm(_p_, false)
 		return
 	}
+	// if it has GC work, start it straight away
+	if gcBlackenEnabled != 0 && gcMarkWorkAvailable(_p_) {
+		startm(_p_, false)
+		return
+	}
 	// no local work, check that there are no spinning/idle M's,
 	// otherwise our help is not required
 	if atomic.Load(&sched.nmspinning)+atomic.Load(&sched.npidle) == 0 && atomic.Cas(&sched.nmspinning, 0, 1) { // TODO: fast atomic
@@ -1787,6 +1795,10 @@
 func findrunnable() (gp *g, inheritTime bool) {
 	_g_ := getg()
 
+	// The conditions here and in handoffp must agree: if
+	// findrunnable would return a G to run, handoffp must start
+	// an M.
+
 top:
 	if sched.gcwaiting != 0 {
 		gcstopm()
diff --git a/src/runtime/sys_darwin_386.s b/src/runtime/sys_darwin_386.s
index c516ef2..ad3dca4 100644
--- a/src/runtime/sys_darwin_386.s
+++ b/src/runtime/sys_darwin_386.s
@@ -242,15 +242,21 @@
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
-TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
-	MOVL	sig+4(FP), AX
-	MOVL	AX, 0(SP)
-	MOVL	info+8(FP), AX
-	MOVL	AX, 4(SP)
-	MOVL	ctx+12(FP), AX
-	MOVL	AX, 8(SP)
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
 	MOVL	fn+0(FP), AX
+	MOVL	sig+4(FP), BX
+	MOVL	info+8(FP), CX
+	MOVL	ctx+12(FP), DX
+	MOVL	SP, SI
+	SUBL	$32, SP		// align stack; handler might be C code
+	ANDL	$~15, SP
+	MOVL	BX, 0(SP)
+	MOVL	CX, 4(SP)
+	MOVL	DX, 8(SP)
+	MOVL	SI, 12(SP)
 	CALL	AX
+	MOVL	12(SP), AX
+	MOVL	AX, SP
 	RET
 
 TEXT runtime·sigreturn(SB),NOSPLIT,$12-8
diff --git a/src/unsafe/unsafe.go b/src/unsafe/unsafe.go
index 33b3114..532fa4a 100644
--- a/src/unsafe/unsafe.go
+++ b/src/unsafe/unsafe.go
@@ -63,7 +63,7 @@
 // (3) Conversion of a Pointer to a uintptr and back, with arithmetic.
 //
 // If p points into an allocated object, it can be advanced through the object
-// by conversion to uintptr, addition of an offset, and conversion back to uintptr.
+// by conversion to uintptr, addition of an offset, and conversion back to Pointer.
 //
 //	p = unsafe.Pointer(uintptr(p) + offset)
 //
diff --git a/test/fixedbugs/issue14164.dir/a.go b/test/fixedbugs/issue14164.dir/a.go
new file mode 100644
index 0000000..bf03051
--- /dev/null
+++ b/test/fixedbugs/issue14164.dir/a.go
@@ -0,0 +1,47 @@
+// Copyright 2016 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.
+
+package a
+
+// F is an exported function, small enough to be inlined.
+// It defines a local interface with an unexported method
+// f, which will appear with a package-qualified method
+// name in the export data.
+func F(x interface{}) bool {
+	_, ok := x.(interface {
+		f()
+	})
+	return ok
+}
+
+// Like F but with the unexported interface method f
+// defined via an embedded interface t. The compiler
+// always flattens embedded interfaces so there should
+// be no difference between F and G. Alas, currently
+// G is not inlineable (at least via export data), so
+// the issue is moot, here.
+func G(x interface{}) bool {
+	type t0 interface {
+		f()
+	}
+	_, ok := x.(interface {
+		t0
+	})
+	return ok
+}
+
+// Like G but now the embedded interface is declared
+// at package level. This function is inlineable via
+// export data. The export data representation is like
+// for F.
+func H(x interface{}) bool {
+	_, ok := x.(interface {
+		t1
+	})
+	return ok
+}
+
+type t1 interface {
+	f()
+}
diff --git a/test/fixedbugs/issue14164.dir/main.go b/test/fixedbugs/issue14164.dir/main.go
new file mode 100644
index 0000000..bcc6a63
--- /dev/null
+++ b/test/fixedbugs/issue14164.dir/main.go
@@ -0,0 +1,12 @@
+// Copyright 2016 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.
+
+package main
+
+// Verify that we can import package "a" containing an inlineable
+// function F that declares a local interface with a non-exported
+// method f.
+import _ "./a"
+
+func main() {}
diff --git a/test/fixedbugs/issue14164.go b/test/fixedbugs/issue14164.go
new file mode 100644
index 0000000..5247599
--- /dev/null
+++ b/test/fixedbugs/issue14164.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2016 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.
+
+ignored