Skip to content

Commit 9f0c76a

Browse files
authored
Merge pull request #2274 from MeteorsLiu/fix/goroot-authoritative-syntax-diagnostics
fix: prefer compiler syntax diagnostics
2 parents d37108c + 3c05bb9 commit 9f0c76a

3 files changed

Lines changed: 48 additions & 44 deletions

File tree

internal/packages/load.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,20 @@ func loadPackageEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
257257
return // not a source package, don't get syntax trees
258258
}
259259

260+
// go list has already captured cmd/compile's authoritative diagnostics in
261+
// this block. For example, an unexpected else stops gc before recovery AST
262+
// errors are reported, so do not append the local parser/type follow-ons.
263+
hasCompilerSyntaxError := false
264+
for _, err := range lpkg.Errors {
265+
if err.Kind != packages.ListError || !strings.HasPrefix(err.Msg, "# ") {
266+
continue
267+
}
268+
if _, diagnostics, ok := strings.Cut(err.Msg, "\n"); ok && strings.Contains(diagnostics, ": syntax error: ") {
269+
hasCompilerSyntaxError = true
270+
break
271+
}
272+
}
273+
260274
appendError := func(err error) {
261275
// Convert various error types into the one true Error.
262276
var errs []packages.Error
@@ -275,6 +289,9 @@ func loadPackageEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
275289

276290
case scanner.ErrorList:
277291
// from parser
292+
if hasCompilerSyntaxError {
293+
return
294+
}
278295
for _, err := range err {
279296
errs = append(errs, packages.Error{
280297
Pos: err.Pos.String(),
@@ -285,6 +302,9 @@ func loadPackageEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
285302

286303
case types.Error:
287304
// from type checker
305+
if hasCompilerSyntaxError {
306+
return
307+
}
288308
lpkg.TypeErrors = append(lpkg.TypeErrors, err)
289309
errs = append(errs, packages.Error{
290310
Pos: err.Fset.Position(err.Pos).String(),

internal/packages/load_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,34 @@ func TestEmbedDiagnosticHelperBoundaries(t *testing.T) {
229229
}
230230

231231
func TestLoadExNormalizesFrontendDiagnostics(t *testing.T) {
232+
t.Run("compiler syntax errors are authoritative", func(t *testing.T) {
233+
dir := t.TempDir()
234+
writeLoadTestFile(t, filepath.Join(dir, "go.mod"), "module example.com/syntaxerror\ngo 1.24\n")
235+
writeLoadTestFile(t, filepath.Join(dir, "load.go"), `package syntaxerror
236+
func f() {
237+
if missing {}
238+
else {}
239+
}
240+
`)
241+
cfg := loadTestConfig(dir)
242+
cfg.BuildFlags = []string{"-gcflags=all=-e"}
243+
cfg.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
244+
return parser.ParseFile(fset, filename, src, parser.AllErrors|parser.ParseComments)
245+
}
246+
pkgs, err := LoadExWithGoVersion(nil, nil, cfg, "go1.24", ".")
247+
if err != nil {
248+
t.Fatal(err)
249+
}
250+
if len(pkgs) != 1 {
251+
t.Fatalf("load returned %d packages, want 1", len(pkgs))
252+
}
253+
pkg := pkgs[0]
254+
assertPackageError(t, pkg, "syntax error:")
255+
for _, secondary := range []string{"expected statement", "found 'EOF'", "undefined: missing"} {
256+
assertPackageErrorAbsent(t, pkg, secondary)
257+
}
258+
})
259+
232260
t.Run("embed local var", func(t *testing.T) {
233261
dir := t.TempDir()
234262
writeLoadTestFile(t, filepath.Join(dir, "go.mod"), "module example.com/embedlocal\ngo 1.24\n")

test/goroot/xfail.yaml

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,54 +1818,10 @@ flakes:
18181818
case: fixedbugs/issue25897a.go
18191819
reason: reflect-generated goroutines under a single-P continuous-GC loop can complete or exceed the 1m run timeout on darwin/arm64
18201820
xfails:
1821-
- version: go1.26
1822-
directive: errorcheck
1823-
case: fixedbugs/issue23664.go
1824-
reason: llgo parser recovery emits additional malformed-declaration diagnostics
1825-
- version: go1.26
1826-
directive: errorcheck
1827-
case: fixedbugs/issue33386.go
1828-
reason: llgo parser recovery emits additional malformed-go/defer diagnostics
1829-
- version: go1.26
1830-
directive: errorcheck
1831-
case: fixedbugs/bug349.go
1832-
reason: llgo parser recovery emits additional return-value diagnostics
1833-
- version: go1.26
1834-
directive: errorcheck
1835-
case: fixedbugs/issue23587.go
1836-
reason: llgo parser recovery emits additional invalid-tilde diagnostics
1837-
- version: go1.26
1838-
directive: errorcheck
1839-
case: syntax/semi7.go
1840-
reason: llgo parser recovery emits additional semicolon and else diagnostics
1841-
- version: go1.26
1842-
directive: errorcheck
1843-
case: fixedbugs/bug274.go
1844-
reason: llgo parser recovery emits additional case and label diagnostics
1845-
- version: go1.26
1846-
directive: errorcheck
1847-
case: fixedbugs/issue18092.go
1848-
reason: llgo parser recovery emits additional malformed-channel diagnostics
18491821
- version: go1.26
18501822
directive: errorcheck
18511823
case: fixedbugs/issue4776.go
18521824
reason: llgo parser uses a different missing-package-clause diagnostic
1853-
- version: go1.26
1854-
directive: errorcheck
1855-
case: switch2.go
1856-
reason: llgo parser recovery emits additional malformed-switch diagnostics
1857-
- version: go1.26
1858-
directive: errorcheck
1859-
case: fixedbugs/issue13319.go
1860-
reason: llgo parser recovery emits additional malformed-call diagnostics
1861-
- version: go1.26
1862-
directive: errorcheck
1863-
case: syntax/semi5.go
1864-
reason: llgo parser recovery emits additional semicolon and end-of-file diagnostics
1865-
- version: go1.26
1866-
directive: errorcheck
1867-
case: fixedbugs/issue13274.go
1868-
reason: llgo parser emits an additional end-of-file diagnostic
18691825
- version: go1.26
18701826
directive: errorcheck
18711827
case: fixedbugs/issue4405.go

0 commit comments

Comments
 (0)