Skip to content

Commit 3360a44

Browse files
authored
Disallow non-lhs all-underscore variable names (#57626)
Addresses part of #57547. Currently, we only show the "all-underscore variable name not allowed" error when the offending symbol is in value position according to `compile`, but an earlier pass would keep them as raw symbols regardless. This led to raw symbols making their way out of lowering in an edge case. This change: Reject all-underscore variables unless they're being written to. Also, improve an error message slighly.
1 parent d934b03 commit 3360a44

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

src/julia-syntax.scm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4659,9 +4659,9 @@ f(x) = yt(x)
46594659
(let ((e1 (if (and arg-map (symbol? e))
46604660
(get arg-map e e)
46614661
e)))
4662-
(if (and value (or (underscore-symbol? e)
4663-
(and (pair? e) (eq? (car e) 'globalref)
4664-
(underscore-symbol? (cadr e)))))
4662+
(if (or (underscore-symbol? e)
4663+
(and (pair? e) (eq? (car e) 'globalref)
4664+
(underscore-symbol? (cadr e))))
46654665
(error (string "all-underscore identifiers are write-only and their values cannot be used in expressions" (format-loc current-loc))))
46664666
(cond (tail (emit-return tail e1))
46674667
(value e1)

src/method.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ static jl_value_t *resolve_definition_effects(jl_value_t *expr, jl_module_t *mod
8484
int binding_effects, int eager_resolve)
8585
{
8686
if (jl_is_symbol(expr)) {
87-
jl_error("Found raw symbol in code returned from lowering. Expected all symbols to have been resolved to GlobalRef or slots.");
87+
jl_errorf("Found raw symbol %s in code returned from lowering. Expected all symbols to have been resolved to GlobalRef or slots.",
88+
jl_symbol_name((jl_sym_t*)expr));
8889
}
8990

9091
if (!jl_is_expr(expr)) {

test/syntax.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2831,6 +2831,20 @@ end
28312831
@m38386
28322832
@test isempty(methods(f38386))
28332833

2834+
@testset "non-lhs all-underscore vars should fail in lowering" begin
2835+
# OK
2836+
@test (_ = 1) === 1
2837+
@test ((_, _) = (1, 2)) == (1, 2)
2838+
@test Meta.isexpr(Meta.lower(Main, :(for _ in 1:2; 1; end)), :thunk)
2839+
@test (try; throw(1); catch _; 2; end) === 2
2840+
@test (let _ = 1; 2; end) === 2
2841+
# ERROR: syntax: all-underscore identifiers are write-only and their values cannot be used in expressions
2842+
@test Meta.isexpr(Meta.lower(Main, :(_ = 1; a = _)), :error)
2843+
@test Meta.isexpr(Meta.lower(Main, :(let; function f(); _; end; end)), :error)
2844+
@test Meta.isexpr(Meta.lower(Main, :(let; function f(); _; 1; end; end)), :error)
2845+
@test Meta.isexpr(Meta.lower(Main, :(begin; _; 1; end)), :error)
2846+
end
2847+
28342848
@testset "all-underscore varargs on the rhs" begin
28352849
@test ncalls_in_lowered(quote _..., = a end, GlobalRef(Base, :rest)) == 0
28362850
@test ncalls_in_lowered(quote ___..., = a end, GlobalRef(Base, :rest)) == 0

0 commit comments

Comments
 (0)