Skip to content

go/parser: ParseExprFrom and ParseExpr might return ast.Expr(nil) when AllErrors is unset #70731

Open
@mateusz834

Description

@mateusz834

ParseExprFrom is documented as such:

// If the source couldn't be read, the returned AST is nil and the error
// indicates the specific failure. If the source was read but syntax
// errors were found, the result is a partial AST (with [ast.Bad]* nodes
// representing the fragments of erroneous source code). Multiple errors
// are returned via a scanner.ErrorList which is sorted by source position.
func ParseExprFrom(fset *token.FileSet, filename string, src any, mode Mode) (expr ast.Expr, err error) {

From the docs it is clear that, if reading the source succeeds, then the returned Expr shoudn't be nil, but it is not actually true (in case of a bailout, also see #70725).

Reproducer:

func TestEarlyBailout2(t *testing.T) {
	const src = `func() {
		func () { var a }
		func () { var a }
		func () { var a }
		func () { var a }
		func () { var a }
		func () { var a }
		func () { var a }
		func () { var a }
		func () { var a }
		func () { var a }
		func () { var a }
		func () { var a }
		func () { var a }
}()
`

	fset := token.NewFileSet()
	expr, err := ParseExprFrom(fset, "test.go", src, SkipObjectResolution|ParseComments)
	t.Log(expr, err) // <nil> test.go:2:19: expected type, found '}' (and 10 more errors)
}

Same with ParseExpr:

// If syntax errors were found, the result is a partial AST (with [ast.Bad]* nodes
// representing the fragments of erroneous source code). Multiple errors are
// returned via a scanner.ErrorList which is sorted by source position.
func ParseExpr(x string) (ast.Expr, error) {
return ParseExprFrom(token.NewFileSet(), "", []byte(x), 0)
}

Per docs it should not return a nil ast.Expr.

CC @griesemer @alandonovan

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions