Skip to content

Panic "Cannot add pos to new symbol" when multiple struct fields share an anonymous struct as their type (concise syntax) #94

@qaisjp

Description

@qaisjp

Summary

A dependency of ours is crashing when we run scip-go:

panic: Cannot add pos to new symbol: symbol:"scip-go gomod github.com/rivo/tview 0d02bb78244d `github.com/rivo/tview`/TextArea#cursor.row."  documentation:"```go\nstruct field row int\n```" symbol:"scip-go gomod github.com/rivo/tview 0d02bb78244d `github.com/rivo/tview`/TextArea#cursor.selectionStart.row."  documentation:"```go\nstruct field row int\n```"

Full log output of time scip-go:

➜ time scip-go
scip-go
Resolving module name
  Go standard library version:  go1.18
  Resolved module name       :  github.com/rivo/tview

Configuration:
  Skip Implementations: false
  Skip Test           : false
Loading Packages
Visiting Packages
panic: Cannot add pos to new symbol: symbol:"scip-go gomod github.com/rivo/tview 0d02bb78244d `github.com/rivo/tview`/TextArea#cursor.row."  documentation:"```go\nstruct field row int\n```" symbol:"scip-go gomod github.com/rivo/tview 0d02bb78244d `github.com/rivo/tview`/TextArea#cursor.selectionStart.row."  documentation:"```go\nstruct field row int\n```"

goroutine 1793 [running]:
github.com/sourcegraph/scip-go/internal/lookup.(*Package).Set(0x1400ad46320, 0x9dcd19, 0x1400ea19400)
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/lookup/lookup.go:51 +0xf8
github.com/sourcegraph/scip-go/internal/document.(*Document).SetNewSymbolForPos(0x1400e9dd110, {0x1400ea00780, 0x6c}, {0x0?, 0x0?}, 0x1401530f6e0?, 0x9dcd19)
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/document/document.go:103 +0x378
github.com/sourcegraph/scip-go/internal/document.(*Document).SetNewSymbol(...)
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/document/document.go:69
github.com/sourcegraph/scip-go/internal/visitors.typeVisitor.Visit({0x1400e9dd110, 0x140004eb980, 0x1400ea02330, 0x14015311880, 0x0}, {0x10094ec90, 0x140153113c0})
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/visitors/visitor_type.go:117 +0x764
go/ast.Walk({0x10094c400?, 0x1400ea05e30?}, {0x10094ec90, 0x140153113c0})
	/opt/homebrew/Cellar/go/1.22.0/libexec/src/go/ast/walk.go:51 +0x44
go/ast.Walk({0x10094c400?, 0x1400ea05dd0?}, {0x10094ece0, 0x14015303260})
	/opt/homebrew/Cellar/go/1.22.0/libexec/src/go/ast/walk.go:85 +0x1e68
go/ast.Walk({0x10094c400?, 0x1400ea05d70?}, {0x10094ef60, 0x1401532a708})
	/opt/homebrew/Cellar/go/1.22.0/libexec/src/go/ast/walk.go:168 +0xdc8
github.com/sourcegraph/scip-go/internal/visitors.typeVisitor.Visit({0x1400e9dd110, 0x140004eb980, 0x1400ea02330, 0x14015311880, 0x0}, {0x10094ec90, 0x14015311440})
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/visitors/visitor_type.go:149 +0xe84
go/ast.Walk({0x10094c400?, 0x1400ea04990?}, {0x10094ec90, 0x14015311440})
	/opt/homebrew/Cellar/go/1.22.0/libexec/src/go/ast/walk.go:51 +0x44
go/ast.Walk({0x10094c400?, 0x1400ea04930?}, {0x10094ece0, 0x140153033e0})
	/opt/homebrew/Cellar/go/1.22.0/libexec/src/go/ast/walk.go:85 +0x1e68
go/ast.Walk({0x10094c400?, 0x1400ea048d0?}, {0x10094ef60, 0x1401532aaf8})
	/opt/homebrew/Cellar/go/1.22.0/libexec/src/go/ast/walk.go:168 +0xdc8
github.com/sourcegraph/scip-go/internal/visitors.typeVisitor.Visit({0x1400e9dd110, 0x140004eb980, 0x1400ea02330, 0x14015311880, 0x0}, {0x10094f370, 0x14015310c40})
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/visitors/visitor_type.go:94 +0x488
go/ast.Walk({0x10094c400?, 0x1400ea04810?}, {0x10094f370, 0x14015310c40})
	/opt/homebrew/Cellar/go/1.22.0/libexec/src/go/ast/walk.go:51 +0x44
github.com/sourcegraph/scip-go/internal/visitors.typeVisitor.Visit({0x1400e9dd110, 0x140004eb980, 0x1400ea02330, 0x0, 0x0}, {0x10094f3c0, 0x14015311880})
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/visitors/visitor_type.go:63 +0x4f0
go/ast.Walk({0x10094c400?, 0x1400e9dd1a0?}, {0x10094f3c0, 0x14015311880})
	/opt/homebrew/Cellar/go/1.22.0/libexec/src/go/ast/walk.go:51 +0x44
go/ast.walkDeclList(...)
	/opt/homebrew/Cellar/go/1.22.0/libexec/src/go/ast/walk.go:38
go/ast.Walk({0x10094c400?, 0x1400e9dd140?}, {0x10094e908, 0x14012e6cf00})
	/opt/homebrew/Cellar/go/1.22.0/libexec/src/go/ast/walk.go:366 +0x2e14
github.com/sourcegraph/scip-go/internal/visitors.visitTypesInFile(0x1400e9dd110, 0x140004eb980, 0x14012e6cf00)
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/visitors/visitor_type.go:19 +0x11c
github.com/sourcegraph/scip-go/internal/visitors.visitSyntax(0x140004eb980, 0x1400ad46320, 0x14012e6cf00, {0x1400003ed3b, 0xb})
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/visitors/visitors.go:45 +0xd4
github.com/sourcegraph/scip-go/internal/visitors.VisitPackageSyntax({0x1400003b8c0, 0x1a}, 0x140004eb980, 0x1400bace2a0, 0x1400a90adf8)
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/visitors/visitors.go:30 +0x138
github.com/sourcegraph/scip-go/internal/index.indexVisitPackages.func1()
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/index/scip.go:191 +0xf8
created by github.com/sourcegraph/scip-go/internal/index.indexVisitPackages in goroutine 1
	/Users/qaisjp/go/pkg/mod/github.com/sourcegraph/scip-go@v0.1.12/internal/index/scip.go:186 +0x220
scip-go  1.88s user 0.73s system 44% cpu 5.948 total

Reproduction steps

  1. Clone https://github.com/rivo/tview (HEAD as of writing is rivo/tview@0d02bb7)
  2. Run scip-go

Additional context

The panic is happening here:

func (p *Package) Set(pos token.Pos, symbol *scip.SymbolInformation) {
// TODO: Could remove this once we are 100% confident we're not overlapping...
if original, ok := p.fields[pos]; ok {
if original != symbol {
panic(fmt.Sprintf("Cannot add pos to new symbol: %s %s", original, symbol))
}
}
p.fields[pos] = symbol
}

It's caused by these lines:

 // The cursor always points to the next position where a new character would
 // be placed. The selection start is the same as cursor as long as there is
 // no selection. When there is one, the selection is between selectionStart
 // and cursor.
 cursor, selectionStart struct {
  // The row and column in screen space but relative to the start of the
  // text which may be outside the text area's box. The column value may
  // be larger than where the cursor actually is if the line the cursor
  // is on is shorter. The actualColumn is the position as it is seen on
  // screen. These three values may not be determined yet, in which case
  // the row is negative.
  row, column, actualColumn int
  
  // The textAreaSpan position with state for the actual next character.
  pos [3]int
 }

The following patch makes the error go away:

diff --git a/textarea.go b/textarea.go
index e6452e3c..116c7439 100644
--- a/textarea.go
+++ b/textarea.go
@@ -89,6 +89,19 @@ type textAreaUndoItem struct {
 	continuation                  bool   // If true, this item is a continuation of the previous undo item. It is handled together with all other undo items in the same continuation sequence.
 }
 
+type cursorOrSelectionStart struct {
+	// The row and column in screen space but relative to the start of the
+	// text which may be outside the text area's box. The column value may
+	// be larger than where the cursor actually is if the line the cursor
+	// is on is shorter. The actualColumn is the position as it is seen on
+	// screen. These three values may not be determined yet, in which case
+	// the row is negative.
+	row, column, actualColumn int
+
+	// The textAreaSpan position with state for the actual next character.
+	pos [3]int
+}
+
 // TextArea implements a simple text editor for multi-line text. Multi-color
 // text is not supported. Word-wrapping is enabled by default but can be turned
 // off or be changed to character-wrapping.
@@ -284,18 +297,8 @@ type TextArea struct {
 	// be placed. The selection start is the same as the cursor as long as there
 	// is no selection. When there is one, the selection is between
 	// selectionStart and cursor.
-	cursor, selectionStart struct {
-		// The row and column in screen space but relative to the start of the
-		// text which may be outside the text area's box. The column value may
-		// be larger than where the cursor actually is if the line the cursor
-		// is on is shorter. The actualColumn is the position as it is seen on
-		// screen. These three values may not be determined yet, in which case
-		// the row is negative.
-		row, column, actualColumn int
-
-		// The textAreaSpan position with state for the actual next character.
-		pos [3]int
-	}
+	cursor         cursorOrSelectionStart
+	selectionStart cursorOrSelectionStart
 
 	// The minimum width of text (if available) to be shown left of the cursor.
 	minCursorPrefix int

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions