go/analysis/passes/nilness: add longer example to doc

Fixes Google Issue 331478795

Change-Id: I0258bdd6a50000effc66c4e1fe03f99e2720c0cc
Reviewed-on: https://go-review.googlesource.com/c/tools/+/575056
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/go/analysis/passes/nilness/doc.go b/go/analysis/passes/nilness/doc.go
index 2122637..e27863e 100644
--- a/go/analysis/passes/nilness/doc.go
+++ b/go/analysis/passes/nilness/doc.go
@@ -42,4 +42,31 @@
 //	if p == nil {
 //		panic(p)
 //	}
+//
+// Sometimes the control flow may be quite complex, making bugs hard
+// to spot. In the example below, the err.Error expression is
+// guaranteed to panic because, after the first return, err must be
+// nil. The intervening loop is just a distraction.
+//
+//	...
+//	err := g.Wait()
+//	if err != nil {
+//		return err
+//	}
+//	partialSuccess := false
+//	for _, err := range errs {
+//		if err == nil {
+//			partialSuccess = true
+//			break
+//		}
+//	}
+//	if partialSuccess {
+//		reportStatus(StatusMessage{
+//			Code:   code.ERROR,
+//			Detail: err.Error(), // "nil dereference in dynamic method call"
+//		})
+//		return nil
+//	}
+//
+// ...
 package nilness
diff --git a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md
index 8532ac1..a7b72e5 100644
--- a/gopls/doc/analyzers.md
+++ b/gopls/doc/analyzers.md
@@ -479,6 +479,33 @@
 		panic(p)
 	}
 
+Sometimes the control flow may be quite complex, making bugs hard
+to spot. In the example below, the err.Error expression is
+guaranteed to panic because, after the first return, err must be
+nil. The intervening loop is just a distraction.
+
+	...
+	err := g.Wait()
+	if err != nil {
+		return err
+	}
+	partialSuccess := false
+	for _, err := range errs {
+		if err == nil {
+			partialSuccess = true
+			break
+		}
+	}
+	if partialSuccess {
+		reportStatus(StatusMessage{
+			Code:   code.ERROR,
+			Detail: err.Error(), // "nil dereference in dynamic method call"
+		})
+		return nil
+	}
+
+...
+
 [Full documentation](https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/nilness)
 
 **Enabled by default.**
diff --git a/gopls/internal/settings/api_json.go b/gopls/internal/settings/api_json.go
index 0f2f231..5e7abf0 100644
--- a/gopls/internal/settings/api_json.go
+++ b/gopls/internal/settings/api_json.go
@@ -340,7 +340,7 @@
 						},
 						{
 							Name:    "\"nilness\"",
-							Doc:     "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}",
+							Doc:     "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}\n\nSometimes the control flow may be quite complex, making bugs hard\nto spot. In the example below, the err.Error expression is\nguaranteed to panic because, after the first return, err must be\nnil. The intervening loop is just a distraction.\n\n\t...\n\terr := g.Wait()\n\tif err != nil {\n\t\treturn err\n\t}\n\tpartialSuccess := false\n\tfor _, err := range errs {\n\t\tif err == nil {\n\t\t\tpartialSuccess = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif partialSuccess {\n\t\treportStatus(StatusMessage{\n\t\t\tCode:   code.ERROR,\n\t\t\tDetail: err.Error(), // \"nil dereference in dynamic method call\"\n\t\t})\n\t\treturn nil\n\t}\n\n...",
 							Default: "true",
 						},
 						{
@@ -1121,7 +1121,7 @@
 		},
 		{
 			Name:    "nilness",
-			Doc:     "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}",
+			Doc:     "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}\n\nSometimes the control flow may be quite complex, making bugs hard\nto spot. In the example below, the err.Error expression is\nguaranteed to panic because, after the first return, err must be\nnil. The intervening loop is just a distraction.\n\n\t...\n\terr := g.Wait()\n\tif err != nil {\n\t\treturn err\n\t}\n\tpartialSuccess := false\n\tfor _, err := range errs {\n\t\tif err == nil {\n\t\t\tpartialSuccess = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif partialSuccess {\n\t\treportStatus(StatusMessage{\n\t\t\tCode:   code.ERROR,\n\t\t\tDetail: err.Error(), // \"nil dereference in dynamic method call\"\n\t\t})\n\t\treturn nil\n\t}\n\n...",
 			URL:     "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/nilness",
 			Default: true,
 		},