Skip to content

Commit

Permalink
lower top-level statements in such a way that the front-end knows
Browse files Browse the repository at this point in the history
their values are not used

fixes most false positives in the deprecation for using the value of `.=`
  • Loading branch information
JeffBezanson committed Mar 3, 2018
1 parent ce26ed0 commit 9badfc2
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 7 deletions.
18 changes: 17 additions & 1 deletion src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,11 @@ jl_value_t *jl_parse_eval_all(const char *fname,
form = jl_expand_macros(form, inmodule, NULL, 0);
expression = julia_to_scm(fl_ctx, form);
}
expression = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-expand-to-thunk")), expression);
// expand non-final expressions in statement position (value unused)
expression =
fl_applyn(fl_ctx, 1,
symbol_value(symbol(fl_ctx, iscons(cdr_(ast)) ? "jl-expand-to-thunk-stmt" : "jl-expand-to-thunk")),
expression);
}
jl_get_ptls_states()->world_age = jl_world_counter;
form = scm_to_julia(fl_ctx, expression, inmodule);
Expand Down Expand Up @@ -1115,6 +1119,18 @@ JL_DLLEXPORT jl_value_t *jl_expand(jl_value_t *expr, jl_module_t *inmodule)
return expr;
}

// expand in a context where the expression value is unused
JL_DLLEXPORT jl_value_t *jl_expand_stmt(jl_value_t *expr, jl_module_t *inmodule)
{
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0);
expr = jl_call_scm_on_ast("jl-expand-to-thunk-stmt", expr, inmodule);
JL_GC_POP();
return expr;
}


#ifdef __cplusplus
}
Expand Down
17 changes: 12 additions & 5 deletions src/jlfrontend.scm
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,14 @@

(define *in-expand* #f)

(define (toplevel-only-expr? e)
(and (pair? e)
(or (memq (car e) '(toplevel line module import importall using export
error incomplete))
(and (eq? (car e) 'global) (every symbol? (cdr e))))))

(define (expand-toplevel-expr e)
(cond ((or (atom? e)
(and (pair? e)
(or (memq (car e) '(toplevel line module import importall using export
error incomplete))
(and (eq? (car e) 'global) (every symbol? (cdr e))))))
(cond ((or (atom? e) (toplevel-only-expr? e))
(if (underscore-symbol? e)
(syntax-deprecation "underscores as an rvalue" "" #f))
e)
Expand Down Expand Up @@ -207,6 +209,11 @@
(parser-wrap (lambda ()
(expand-toplevel-expr expr))))

(define (jl-expand-to-thunk-stmt expr)
(jl-expand-to-thunk (if (toplevel-only-expr? expr)
expr
`(block ,expr (null)))))

; run whole frontend on a string. useful for testing.
(define (fe str)
(expand-toplevel-expr (julia-parse str)))
Expand Down
1 change: 1 addition & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,7 @@ JL_DLLEXPORT jl_value_t *jl_parse_string(const char *str, size_t len,
JL_DLLEXPORT jl_value_t *jl_load_file_string(const char *text, size_t len,
char *filename, jl_module_t *inmodule);
JL_DLLEXPORT jl_value_t *jl_expand(jl_value_t *expr, jl_module_t *inmodule);
JL_DLLEXPORT jl_value_t *jl_expand_stmt(jl_value_t *expr, jl_module_t *inmodule);
JL_DLLEXPORT jl_value_t *jl_eval_string(const char *str);

// external libraries
Expand Down
2 changes: 1 addition & 1 deletion src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex)
for (int i = 0; i < jl_array_len(exprs); i++) {
// process toplevel form
ptls->world_age = jl_world_counter;
form = jl_expand(jl_array_ptr_ref(exprs, i), newm);
form = jl_expand_stmt(jl_array_ptr_ref(exprs, i), newm);
ptls->world_age = jl_world_counter;
(void)jl_toplevel_eval_flex(newm, form, 1, 1);
}
Expand Down
12 changes: 12 additions & 0 deletions test/deprecation_exec.jl
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,18 @@ end
# #6080
@test_deprecated r"Syntax `&argument`.*is deprecated" Meta.lower(@__MODULE__, :(ccall(:a, Cvoid, (Cint,), &x)))

@test_logs eval(:(module DotEqualsDep
a=[1,2]
a.=3
0
end))
@test_logs include_string(@__MODULE__, """
a=[1,2]
a.=3
0""")
@test_deprecated include_string(@__MODULE__, """
a=[1,2]
a.=3""")
end

module LogTest
Expand Down

0 comments on commit 9badfc2

Please sign in to comment.