all: merge master (43b469a) into gopls-release-branch.0.7

Merge List:

+ 2021-11-17 43b469a3 go/analysis/passes/printf: update logic now that type parameters are interfaces
+ 2021-11-17 771dabf4 gopls/internal/regtest/misc: skip TestInconsistentVendoring on Windows
+ 2021-11-17 7d6c71f2 internal/lsp/source/completion: avoid invalid AST in enclosingSignature

Change-Id: I7926670ad4f2897ac4951f08ad37df9b39222847
diff --git a/go/analysis/passes/printf/printf.go b/go/analysis/passes/printf/printf.go
index 0206073..dee37d7 100644
--- a/go/analysis/passes/printf/printf.go
+++ b/go/analysis/passes/printf/printf.go
@@ -25,6 +25,7 @@
 	"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
 	"golang.org/x/tools/go/ast/inspector"
 	"golang.org/x/tools/go/types/typeutil"
+	"golang.org/x/tools/internal/typeparams"
 )
 
 func init() {
@@ -520,7 +521,12 @@
 func isFormatter(typ types.Type) bool {
 	// If the type is an interface, the value it holds might satisfy fmt.Formatter.
 	if _, ok := typ.Underlying().(*types.Interface); ok {
-		return true
+		// Don't assume type parameters could be formatters. With the greater
+		// expressiveness of constraint interface syntax we expect more type safety
+		// when using type parameters.
+		if !typeparams.IsTypeParam(typ) {
+			return true
+		}
 	}
 	obj, _, _ := types.LookupFieldOrMethod(typ, false, nil, "Format")
 	fn, ok := obj.(*types.Func)
diff --git a/go/analysis/passes/printf/types.go b/go/analysis/passes/printf/types.go
index 81bf36e..270e917 100644
--- a/go/analysis/passes/printf/types.go
+++ b/go/analysis/passes/printf/types.go
@@ -178,10 +178,12 @@
 			return true
 		}
 
+		if typeparams.IsTypeParam(typ.Elem()) {
+			return true // We don't know whether the logic below applies. Give up.
+		}
+
 		under := typ.Elem().Underlying()
 		switch under.(type) {
-		case *typeparams.TypeParam:
-			return true // We don't know whether the logic below applies. Give up.
 		case *types.Struct: // see below
 		case *types.Array: // see below
 		case *types.Slice: // see below
diff --git a/gopls/internal/regtest/misc/vendor_test.go b/gopls/internal/regtest/misc/vendor_test.go
index 4e02799..0e615f2 100644
--- a/gopls/internal/regtest/misc/vendor_test.go
+++ b/gopls/internal/regtest/misc/vendor_test.go
@@ -5,6 +5,7 @@
 package misc
 
 import (
+	"runtime"
 	"testing"
 
 	. "golang.org/x/tools/internal/lsp/regtest"
@@ -26,6 +27,9 @@
 
 func TestInconsistentVendoring(t *testing.T) {
 	testenv.NeedsGo1Point(t, 14)
+	if runtime.GOOS == "windows" {
+		t.Skipf("skipping test due to flakiness on Windows: https://golang.org/issue/49646")
+	}
 
 	const pkgThatUsesVendoring = `
 -- go.mod --
diff --git a/internal/lsp/source/completion/completion.go b/internal/lsp/source/completion/completion.go
index dbc380c..94389c7 100644
--- a/internal/lsp/source/completion/completion.go
+++ b/internal/lsp/source/completion/completion.go
@@ -1694,6 +1694,12 @@
 			}
 		case *ast.FuncLit:
 			if typ, ok := info.Types[t]; ok {
+				if sig, _ := typ.Type.(*types.Signature); sig == nil {
+					// golang/go#49397: it should not be possible, but we somehow arrived
+					// here with a non-signature type, most likely due to AST mangling
+					// such that node.Type is not a FuncType.
+					return nil
+				}
 				return &funcInfo{
 					sig:  typ.Type.(*types.Signature),
 					body: t.Body,
diff --git a/internal/typeparams/common.go b/internal/typeparams/common.go
index 9fc6b4b..961d036 100644
--- a/internal/typeparams/common.go
+++ b/internal/typeparams/common.go
@@ -13,6 +13,7 @@
 import (
 	"go/ast"
 	"go/token"
+	"go/types"
 )
 
 // A IndexExprData holds data from both ast.IndexExpr and the new
@@ -23,3 +24,9 @@
 	Indices []ast.Expr // index expressions
 	Rbrack  token.Pos  // position of "]"
 }
+
+// IsTypeParam reports whether t is a type parameter.
+func IsTypeParam(t types.Type) bool {
+	_, ok := t.(*TypeParam)
+	return ok
+}