[dev.go2go] all: support the go2-dev go/types library in x/tools

Most notably, this change allows gopls to compile with the new go/types,
allowing it to work with the generics prototype.

This change will fail on TryBots, as it requires a new version of the
Go standard library. This will only be used to tag a go2go-compatible
version of gopls.

Change-Id: I6b43272d70dc4e92e151df259b5003b353c97d30
Reviewed-on: https://go-review.googlesource.com/c/tools/+/238258
Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/go/internal/gcimporter/bimport.go b/go/internal/gcimporter/bimport.go
index e9f73d1..b2d04c4 100644
--- a/go/internal/gcimporter/bimport.go
+++ b/go/internal/gcimporter/bimport.go
@@ -396,6 +396,23 @@
 func (t *dddSlice) Underlying() types.Type { return t }
 func (t *dddSlice) String() string         { return "..." + t.elem.String() }
 
+// Implement the go2-dev go/types.Type interface, to allow x/tools to compile
+// with the go2 prototype. See https://blog.golang.org/generics-next-step.
+func (t *dddSlice) Under() types.Type           { return t }
+func (t *dddSlice) Basic() *types.Basic         { panic("unimplemented") }
+func (t *dddSlice) Array() *types.Array         { panic("unimplemented") }
+func (t *dddSlice) Slice() *types.Slice         { panic("unimplemented") }
+func (t *dddSlice) Struct() *types.Struct       { panic("unimplemented") }
+func (t *dddSlice) Pointer() *types.Pointer     { panic("unimplemented") }
+func (t *dddSlice) Tuple() *types.Tuple         { panic("unimplemented") }
+func (t *dddSlice) Signature() *types.Signature { panic("unimplemented") }
+func (t *dddSlice) Sum() *types.Sum             { panic("unimplemented") }
+func (t *dddSlice) Interface() *types.Interface { panic("unimplemented") }
+func (t *dddSlice) Map() *types.Map             { panic("unimplemented") }
+func (t *dddSlice) Chan() *types.Chan           { panic("unimplemented") }
+func (t *dddSlice) Named() *types.Named         { panic("unimplemented") }
+func (t *dddSlice) TypeParam() *types.TypeParam { panic("unimplemented") }
+
 // parent is the package which declared the type; parent == nil means
 // the package currently imported. The parent package is needed for
 // exported struct fields and interface methods which don't contain
@@ -1037,3 +1054,20 @@
 
 func (t anyType) Underlying() types.Type { return t }
 func (t anyType) String() string         { return "any" }
+
+// Implement the go2-dev go/types.Type interface, to allow x/tools to compile
+// with the go2 prototype. See https://blog.golang.org/generics-next-step.
+func (t anyType) Under() types.Type           { return t }
+func (t anyType) Basic() *types.Basic         { panic("unimplemented") }
+func (t anyType) Array() *types.Array         { panic("unimplemented") }
+func (t anyType) Slice() *types.Slice         { panic("unimplemented") }
+func (t anyType) Struct() *types.Struct       { panic("unimplemented") }
+func (t anyType) Pointer() *types.Pointer     { panic("unimplemented") }
+func (t anyType) Tuple() *types.Tuple         { panic("unimplemented") }
+func (t anyType) Signature() *types.Signature { panic("unimplemented") }
+func (t anyType) Sum() *types.Sum             { panic("unimplemented") }
+func (t anyType) Interface() *types.Interface { panic("unimplemented") }
+func (t anyType) Map() *types.Map             { panic("unimplemented") }
+func (t anyType) Chan() *types.Chan           { panic("unimplemented") }
+func (t anyType) Named() *types.Named         { panic("unimplemented") }
+func (t anyType) TypeParam() *types.TypeParam { panic("unimplemented") }
diff --git a/internal/lsp/completion.go b/internal/lsp/completion.go
index bca9a83..380e9b1 100644
--- a/internal/lsp/completion.go
+++ b/internal/lsp/completion.go
@@ -16,6 +16,13 @@
 )
 
 func (s *Server) completion(ctx context.Context, params *protocol.CompletionParams) (*protocol.CompletionList, error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r == "unreachable" {
+				event.Log(ctx, "panicked due to go2")
+			}
+		}
+	}()
 	snapshot, fh, ok, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
 	if !ok {
 		return nil, err
diff --git a/internal/lsp/hover.go b/internal/lsp/hover.go
index e9eaddf..09ed478 100644
--- a/internal/lsp/hover.go
+++ b/internal/lsp/hover.go
@@ -7,12 +7,20 @@
 import (
 	"context"
 
+	"golang.org/x/tools/internal/event"
 	"golang.org/x/tools/internal/lsp/mod"
 	"golang.org/x/tools/internal/lsp/protocol"
 	"golang.org/x/tools/internal/lsp/source"
 )
 
 func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*protocol.Hover, error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r == "unreachable" {
+				event.Log(ctx, "panicked due to go2")
+			}
+		}
+	}()
 	snapshot, fh, ok, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
 	if !ok {
 		return nil, err
diff --git a/internal/lsp/references.go b/internal/lsp/references.go
index 8d65bf9..474f4c1 100644
--- a/internal/lsp/references.go
+++ b/internal/lsp/references.go
@@ -7,11 +7,20 @@
 import (
 	"context"
 
+	"golang.org/x/tools/internal/event"
 	"golang.org/x/tools/internal/lsp/protocol"
 	"golang.org/x/tools/internal/lsp/source"
 )
 
 func (s *Server) references(ctx context.Context, params *protocol.ReferenceParams) ([]protocol.Location, error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r == "unreachable" {
+				event.Log(ctx, "panicked due to go2")
+			}
+		}
+	}()
+
 	snapshot, fh, ok, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go)
 	if !ok {
 		return nil, err
diff --git a/internal/lsp/rename.go b/internal/lsp/rename.go
index cbd06ec..53c1b8d 100644
--- a/internal/lsp/rename.go
+++ b/internal/lsp/rename.go
@@ -7,11 +7,20 @@
 import (
 	"context"
 
+	"golang.org/x/tools/internal/event"
 	"golang.org/x/tools/internal/lsp/protocol"
 	"golang.org/x/tools/internal/lsp/source"
 )
 
 func (s *Server) rename(ctx context.Context, params *protocol.RenameParams) (*protocol.WorkspaceEdit, error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r == "unreachable" {
+				event.Log(ctx, "panicked due to go2")
+			}
+		}
+	}()
+
 	snapshot, fh, ok, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go)
 	if !ok {
 		return nil, err
@@ -35,6 +44,14 @@
 }
 
 func (s *Server) prepareRename(ctx context.Context, params *protocol.PrepareRenameParams) (*protocol.Range, error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r == "unreachable" {
+				event.Log(ctx, "panicked due to go2")
+			}
+		}
+	}()
+
 	snapshot, fh, ok, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go)
 	if !ok {
 		return nil, err
diff --git a/internal/lsp/signature_help.go b/internal/lsp/signature_help.go
index 87dfeb0..0e54df5 100644
--- a/internal/lsp/signature_help.go
+++ b/internal/lsp/signature_help.go
@@ -14,6 +14,14 @@
 )
 
 func (s *Server) signatureHelp(ctx context.Context, params *protocol.SignatureHelpParams) (*protocol.SignatureHelp, error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r == "unreachable" {
+				event.Log(ctx, "panicked due to go2")
+			}
+		}
+	}()
+
 	snapshot, fh, ok, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go)
 	if !ok {
 		return nil, err
diff --git a/internal/lsp/symbols.go b/internal/lsp/symbols.go
index 0f101a6..b534108 100644
--- a/internal/lsp/symbols.go
+++ b/internal/lsp/symbols.go
@@ -14,6 +14,14 @@
 )
 
 func (s *Server) documentSymbol(ctx context.Context, params *protocol.DocumentSymbolParams) ([]interface{}, error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r == "unreachable" {
+				event.Log(ctx, "panicked due to go2")
+			}
+		}
+	}()
+
 	ctx, done := event.Start(ctx, "lsp.Server.documentSymbol")
 	defer done()
 
diff --git a/internal/lsp/workspace_symbol.go b/internal/lsp/workspace_symbol.go
index a233d44..2eb5129 100644
--- a/internal/lsp/workspace_symbol.go
+++ b/internal/lsp/workspace_symbol.go
@@ -13,6 +13,14 @@
 )
 
 func (s *Server) symbol(ctx context.Context, params *protocol.WorkspaceSymbolParams) ([]protocol.SymbolInformation, error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r == "unreachable" {
+				event.Log(ctx, "panicked due to go2")
+			}
+		}
+	}()
+
 	ctx, done := event.Start(ctx, "lsp.Server.symbol")
 	defer done()