diff --git a/src/julia-parser.scm b/src/julia-parser.scm index 97a11df701a37..22d677b8bdaa2 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -1355,11 +1355,19 @@ (list 'where (rewrap-where x (cadr w)) (caddr w)) x)) +(define (parse-struct-field s) + (let ((tok (peek-token s))) + ;; allow `const x` only as a struct field + (if (eq? tok 'const) + (begin (take-token s) + `(const ,(parse-eq s))) + (parse-eq s)))) + (define (parse-struct-def s mut? word) (if (reserved-word? (peek-token s)) (error (string "invalid type name \"" (take-token s) "\""))) (let ((sig (parse-subtype-spec s))) - (begin0 (list 'struct (if mut? '(true) '(false)) sig (parse-block s)) + (begin0 (list 'struct (if mut? '(true) '(false)) sig (parse-block s parse-struct-field)) (expect-end s word)))) ;; consume any number of line endings from a token stream @@ -1456,7 +1464,13 @@ `(const ,expr) expr))) ((const) - `(const ,(parse-eq s))) + (let ((assgn (parse-eq s))) + (if (not (and (pair? assgn) + (or (eq? (car assgn) '=) + (eq? (car assgn) 'global) + (eq? (car assgn) 'local)))) + (error "expected assignment after \"const\"") + `(const ,assgn)))) ((function macro) (let* ((loc (line-number-node s)) diff --git a/test/syntax.jl b/test/syntax.jl index 4784534fdd8c5..3009727fa61bf 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -3369,3 +3369,13 @@ end # issue #45162 f45162(f) = f(x=1) @test first(methods(f45162)).called != 0 + +# issue #45024 +@test_throws ParseError("expected assignment after \"const\"") Meta.parse("const x") +@test_throws ParseError("expected assignment after \"const\"") Meta.parse("const x::Int") +# these cases have always been caught during lowering, since (const (global x)) is not +# ambiguous with the lowered form (const x), but that could probably be changed. +@test Meta.lower(@__MODULE__, :(global const x)) == Expr(:error, "expected assignment after \"const\"") +@test Meta.lower(@__MODULE__, :(global const x::Int)) == Expr(:error, "expected assignment after \"const\"") +@test Meta.lower(@__MODULE__, :(const global x)) == Expr(:error, "expected assignment after \"const\"") +@test Meta.lower(@__MODULE__, :(const global x::Int)) == Expr(:error, "expected assignment after \"const\"")