Skip to content

Commit 9badfc2

Browse files
committed
lower top-level statements in such a way that the front-end knows
their values are not used fixes most false positives in the deprecation for using the value of `.=`
1 parent ce26ed0 commit 9badfc2

File tree

5 files changed

+43
-7
lines changed

5 files changed

+43
-7
lines changed

src/ast.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,11 @@ jl_value_t *jl_parse_eval_all(const char *fname,
829829
form = jl_expand_macros(form, inmodule, NULL, 0);
830830
expression = julia_to_scm(fl_ctx, form);
831831
}
832-
expression = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-expand-to-thunk")), expression);
832+
// expand non-final expressions in statement position (value unused)
833+
expression =
834+
fl_applyn(fl_ctx, 1,
835+
symbol_value(symbol(fl_ctx, iscons(cdr_(ast)) ? "jl-expand-to-thunk-stmt" : "jl-expand-to-thunk")),
836+
expression);
833837
}
834838
jl_get_ptls_states()->world_age = jl_world_counter;
835839
form = scm_to_julia(fl_ctx, expression, inmodule);
@@ -1115,6 +1119,18 @@ JL_DLLEXPORT jl_value_t *jl_expand(jl_value_t *expr, jl_module_t *inmodule)
11151119
return expr;
11161120
}
11171121

1122+
// expand in a context where the expression value is unused
1123+
JL_DLLEXPORT jl_value_t *jl_expand_stmt(jl_value_t *expr, jl_module_t *inmodule)
1124+
{
1125+
JL_TIMING(LOWERING);
1126+
JL_GC_PUSH1(&expr);
1127+
expr = jl_copy_ast(expr);
1128+
expr = jl_expand_macros(expr, inmodule, NULL, 0);
1129+
expr = jl_call_scm_on_ast("jl-expand-to-thunk-stmt", expr, inmodule);
1130+
JL_GC_POP();
1131+
return expr;
1132+
}
1133+
11181134

11191135
#ifdef __cplusplus
11201136
}

src/jlfrontend.scm

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,14 @@
9494

9595
(define *in-expand* #f)
9696

97+
(define (toplevel-only-expr? e)
98+
(and (pair? e)
99+
(or (memq (car e) '(toplevel line module import importall using export
100+
error incomplete))
101+
(and (eq? (car e) 'global) (every symbol? (cdr e))))))
102+
97103
(define (expand-toplevel-expr e)
98-
(cond ((or (atom? e)
99-
(and (pair? e)
100-
(or (memq (car e) '(toplevel line module import importall using export
101-
error incomplete))
102-
(and (eq? (car e) 'global) (every symbol? (cdr e))))))
104+
(cond ((or (atom? e) (toplevel-only-expr? e))
103105
(if (underscore-symbol? e)
104106
(syntax-deprecation "underscores as an rvalue" "" #f))
105107
e)
@@ -207,6 +209,11 @@
207209
(parser-wrap (lambda ()
208210
(expand-toplevel-expr expr))))
209211

212+
(define (jl-expand-to-thunk-stmt expr)
213+
(jl-expand-to-thunk (if (toplevel-only-expr? expr)
214+
expr
215+
`(block ,expr (null)))))
216+
210217
; run whole frontend on a string. useful for testing.
211218
(define (fe str)
212219
(expand-toplevel-expr (julia-parse str)))

src/julia.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,6 +1450,7 @@ JL_DLLEXPORT jl_value_t *jl_parse_string(const char *str, size_t len,
14501450
JL_DLLEXPORT jl_value_t *jl_load_file_string(const char *text, size_t len,
14511451
char *filename, jl_module_t *inmodule);
14521452
JL_DLLEXPORT jl_value_t *jl_expand(jl_value_t *expr, jl_module_t *inmodule);
1453+
JL_DLLEXPORT jl_value_t *jl_expand_stmt(jl_value_t *expr, jl_module_t *inmodule);
14531454
JL_DLLEXPORT jl_value_t *jl_eval_string(const char *str);
14541455

14551456
// external libraries

src/toplevel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex)
228228
for (int i = 0; i < jl_array_len(exprs); i++) {
229229
// process toplevel form
230230
ptls->world_age = jl_world_counter;
231-
form = jl_expand(jl_array_ptr_ref(exprs, i), newm);
231+
form = jl_expand_stmt(jl_array_ptr_ref(exprs, i), newm);
232232
ptls->world_age = jl_world_counter;
233233
(void)jl_toplevel_eval_flex(newm, form, 1, 1);
234234
}

test/deprecation_exec.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,18 @@ end
209209
# #6080
210210
@test_deprecated r"Syntax `&argument`.*is deprecated" Meta.lower(@__MODULE__, :(ccall(:a, Cvoid, (Cint,), &x)))
211211

212+
@test_logs eval(:(module DotEqualsDep
213+
a=[1,2]
214+
a.=3
215+
0
216+
end))
217+
@test_logs include_string(@__MODULE__, """
218+
a=[1,2]
219+
a.=3
220+
0""")
221+
@test_deprecated include_string(@__MODULE__, """
222+
a=[1,2]
223+
a.=3""")
212224
end
213225

214226
module LogTest

0 commit comments

Comments
 (0)