Skip to content

Commit 3b3100c

Browse files
committed
gopls/internal/golang: recover failed inlineAllCalls
Similar to inlineCall, inlineAllCalls needs to have recovery logic, as the inliner cannot be guaranteed to work on ill-typed input. Fixes golang/go#73912 Fixes golang/go#73913 Change-Id: Ibd471dbfba6efb6e6bcd3539317418501e729f2c Reviewed-on: https://go-review.googlesource.com/c/tools/+/684695 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent d75a88d commit 3b3100c

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

gopls/internal/golang/inline_all.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import (
4444
//
4545
// The code below notes where are assumptions are made that only hold true in
4646
// the case of parameter removal (annotated with 'Assumption:')
47-
func inlineAllCalls(ctx context.Context, snapshot *cache.Snapshot, pkg *cache.Package, pgf *parsego.File, origDecl *ast.FuncDecl, callee *inline.Callee, post func([]byte) []byte, opts *inline.Options) (map[protocol.DocumentURI][]byte, error) {
47+
func inlineAllCalls(ctx context.Context, snapshot *cache.Snapshot, pkg *cache.Package, pgf *parsego.File, origDecl *ast.FuncDecl, callee *inline.Callee, post func([]byte) []byte, opts *inline.Options) (_ map[protocol.DocumentURI][]byte, inlineErr error) {
4848
// Collect references.
4949
var refs []protocol.Location
5050
{
@@ -68,6 +68,11 @@ func inlineAllCalls(ctx context.Context, snapshot *cache.Snapshot, pkg *cache.Pa
6868
var (
6969
pkgForRef = make(map[protocol.Location]PackageID)
7070
pkgs = make(map[PackageID]*cache.Package)
71+
// The inliner assumes that input is well-typed, but that is frequently not
72+
// the case within gopls.
73+
// Until we're able to harden the inliner, report panics as errors to avoid
74+
// crashing the server.
75+
badPkg = false
7176
)
7277
{
7378
needPkgs := make(map[PackageID]struct{})
@@ -91,9 +96,20 @@ func inlineAllCalls(ctx context.Context, snapshot *cache.Snapshot, pkg *cache.Pa
9196

9297
for _, p := range refPkgs {
9398
pkgs[p.Metadata().ID] = p
99+
if len(p.ParseErrors())+len(p.TypeErrors()) > 0 {
100+
badPkg = true
101+
}
94102
}
95103
}
96104

105+
if badPkg {
106+
defer func() {
107+
if x := recover(); x != nil {
108+
inlineErr = fmt.Errorf("inlining failed (%q), likely because inputs were ill-typed", x)
109+
}
110+
}()
111+
}
112+
97113
// Organize calls by top file declaration. Calls within a single file may
98114
// affect each other, as the inlining edit may affect the surrounding scope
99115
// or imports Therefore, when inlining subsequent calls in the same

0 commit comments

Comments
 (0)