// run // Copyright 2026 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Make sure we get the right line number for nil pointer panics. package main import ( "fmt" "runtime/debug" "strings" ) type T struct { a int } func (t *T) foo() { t.a = 3 } func f1() { var t *T (*t).foo() } type U struct { V } type V struct { x int } func (v *V) setX() { v.x = 7 } func f2() { var u *U u.setX() } func check(stack string, good []string, bad []string) { for _, g := range good { if !strings.Contains(stack, g) { fmt.Println(stack) fmt.Printf("ERROR: stack doesn't contain %s\n", g) } } for _, b := range bad { if strings.Contains(stack, b) { fmt.Println(stack) fmt.Printf("ERROR: stack contains %s\n", b) } } } func test1() { defer func() { r := recover() if r == nil { fmt.Println("ERROR: f1 should have panicked") return } check(string(debug.Stack()), []string{"f1", "issue79762.go:27"}, []string{"foo"}) }() f1() } func test2() { defer func() { r := recover() if r == nil { fmt.Println("ERROR: f2 should have panicked") return } check(string(debug.Stack()), []string{"f2", "issue79762.go:43"}, []string{"setX"}) }() f2() } func main() { test1() test2() }