Skip to content

Commit

Permalink
Add file and line number reporting for some lowering errors (JuliaLan…
Browse files Browse the repository at this point in the history
…g#35105)

* Add file and line number reporting for desugaring errors

* Cleanup: use globals jl_filename jl_lineno less
  The various code paths that these globals can be set on are quite
  confusing and the globals can leak between unrelated evaluation
  contexts. Reduce this by using them less.
  • Loading branch information
c42f committed Mar 17, 2020
1 parent c1bd7ef commit 36241a9
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 10 deletions.
12 changes: 8 additions & 4 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,7 @@ jl_value_t *jl_parse_eval_all(const char *fname,
int last_lineno = jl_lineno;
const char *last_filename = jl_filename;
size_t last_age = jl_get_ptls_states()->world_age;
int lineno = 0;
jl_lineno = 0;
jl_filename = fname;
jl_module_t *old_module = ctx->module;
Expand Down Expand Up @@ -894,17 +895,20 @@ jl_value_t *jl_parse_eval_all(const char *fname,
expression =
fl_applyn(fl_ctx, 4,
symbol_value(symbol(fl_ctx, "jl-expand-to-thunk-warn")),
expression, symbol(fl_ctx, jl_filename), fixnum(jl_lineno),
expression, symbol(fl_ctx, fname), fixnum(lineno),
iscons(cdr_(ast)) ? fl_ctx->T : fl_ctx->F);
}
jl_get_ptls_states()->world_age = jl_world_counter;
form = scm_to_julia(fl_ctx, expression, inmodule);
JL_SIGATOMIC_END();
jl_get_ptls_states()->world_age = jl_world_counter;
if (jl_is_linenode(form))
jl_lineno = jl_linenode_line(form);
else
if (jl_is_linenode(form)) {
lineno = jl_linenode_line(form);
jl_lineno = lineno;
}
else {
result = jl_toplevel_eval_flex(inmodule, form, 1, 1);
}
JL_SIGATOMIC_BEGIN();
ast = cdr_(ast);
}
Expand Down
2 changes: 1 addition & 1 deletion src/jlfrontend.scm
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
(let ((ex0 (julia-expand-macroscope e)))
(if (toplevel-only-expr? ex0)
ex0
(let* ((ex (julia-expand0 ex0))
(let* ((ex (julia-expand0 ex0 file line))
(th (julia-expand1
`(lambda () ()
(scope-block
Expand Down
24 changes: 21 additions & 3 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1837,7 +1837,7 @@
`(= ,lhs ,rhs)))

(define (expand-forms e)
(if (or (atom? e) (memq (car e) '(quote inert top core globalref outerref line module toplevel ssavalue null true false meta using import export)))
(if (or (atom? e) (memq (car e) '(quote inert top core globalref outerref module toplevel ssavalue null true false meta using import export)))
e
(let ((ex (get expand-table (car e) #f)))
(if ex
Expand Down Expand Up @@ -2334,6 +2334,11 @@
(= ,r ,(expand-forms (cadr e)))
(gc_preserve_end ,s)
,r)))

'line
(lambda (e)
(set! *current-desugar-loc* e)
e)
))

(define (has-return? e)
Expand Down Expand Up @@ -4368,9 +4373,22 @@ f(x) = yt(x)
(analyze-variables!
(resolve-scopes ex)))) file line))

(define julia-expand0 expand-forms)
(define *current-desugar-loc* #f)

(define (julia-expand0 ex file line)
(with-bindings ((*current-desugar-loc* `(line ,line ,file)))
(trycatch (expand-forms ex)
(lambda (e)
(if (and (pair? e) (eq? (car e) 'error))
; Add location for desugaring errors. This is approximate:
; - Line number nodes are sparse in the AST
; - Line number nodes apply to the next statement, so
; tracking by `set!`ing *current-desugar-loc* relies on
; AST traversal being in program order.
(error (string (cadr e) (format-loc *current-desugar-loc*))))
(raise e)))))

(define (julia-expand ex (file 'none) (line 0))
(julia-expand1
(julia-expand0
(julia-expand-macroscope ex)) file line))
(julia-expand-macroscope ex) file line) file line))
2 changes: 1 addition & 1 deletion src/macroexpand.scm
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
(cons (decl-var (cadar binds)) vars)))
((eventually-call? (cadar binds))
;; f()=c
(let ((asgn (cadr (julia-expand0 (car binds)))))
(let ((asgn (cadr (julia-expand0 (car binds) 'none 0))))
(loop (cdr binds)
(cons (cadr asgn) vars))))
((and (pair? (cadar binds))
Expand Down
3 changes: 3 additions & 0 deletions src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_in(jl_module_t *m, jl_value_t *ex)
jl_error("eval cannot be used in a generated function");
jl_value_t *v = NULL;
int last_lineno = jl_lineno;
const char *last_filename = jl_filename;
if (jl_options.incremental && jl_generating_output()) {
if (!ptrhash_has(&jl_current_modules, (void*)m)) {
if (m != jl_main_module) { // TODO: this was grand-fathered in
Expand All @@ -843,9 +844,11 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_in(jl_module_t *m, jl_value_t *ex)
}
JL_CATCH {
jl_lineno = last_lineno;
jl_filename = last_filename;
jl_rethrow();
}
jl_lineno = last_lineno;
jl_filename = last_filename;
assert(v);
return v;
}
Expand Down
15 changes: 14 additions & 1 deletion test/syntax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,10 @@ end
@test c27964(8) == (8, 2)

# issue #26739
@test_throws ErrorException("syntax: invalid syntax \"sin.[1]\"") Core.eval(@__MODULE__, :(sin.[1]))
let exc = try Core.eval(@__MODULE__, :(sin.[1])) catch exc ; exc end
@test exc isa ErrorException
@test startswith(exc.msg, "syntax: invalid syntax \"sin.[1]\"")
end

# issue #26873
f26873 = 0
Expand Down Expand Up @@ -2182,6 +2185,16 @@ end
end
end

# Syntax desugaring pass errors contain line numbers
@test Meta.lower(@__MODULE__, Expr(:block, LineNumberNode(101, :some_file), :(f(x,x)=1))) ==
Expr(:error, "function argument names not unique around some_file:101")

# Ensure file names don't leak between `eval`s
eval(LineNumberNode(11, :incorrect_file))
let exc = try eval(:(f(x,x)=1)) catch e ; e ; end
@test !occursin("incorrect_file", exc.msg)
end

# issue #34967
@test_throws LoadError("string", 2, ErrorException("syntax: invalid UTF-8 sequence")) include_string(@__MODULE__,
"x34967 = 1\n# Halloa\xf5b\nx34967 = 2")
Expand Down

0 comments on commit 36241a9

Please sign in to comment.