Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions JuliaLowering/src/desugaring.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4459,8 +4459,8 @@ function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs=nothing)
# Convert Symbol (from Expr conversion) to symbolic_label
if label_kind == K"Symbol"
label = @ast ctx label label.name_val::K"symbolic_label"
elseif !(label_kind == K"Identifier" || label_kind == K"symbolic_label" ||
is_contextual_keyword(label_kind))
elseif !(label_kind == K"Identifier" || label_kind == K"Placeholder" ||
label_kind == K"symbolic_label" || is_contextual_keyword(label_kind))
throw(LoweringError(label, "Invalid break label: expected identifier"))
end
if nc == 2
Expand Down
12 changes: 10 additions & 2 deletions JuliaLowering/src/linear_ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,16 @@ function emit_break(ctx, ex)
name = ex[1].name_val
target = get(ctx.break_targets, name, nothing)
if isnothing(target)
ty = name == "loop_exit" ? "break" : "continue"
throw(LoweringError(ex, "$ty must be used inside a `while` or `for` loop"))
if name == "loop_exit"
throw(LoweringError(ex, "`break` must be used inside a `while` or `for` loop"))
elseif name == "loop_cont"
throw(LoweringError(ex, "`continue` must be used inside a `while` or `for` loop"))
elseif endswith(name, "#cont")
label = name[1:end-5]
throw(LoweringError(ex, "`continue $label` is not inside a `@label $label` loop"))
else
throw(LoweringError(ex, "`break $name` is not inside a `@label $name` block"))
end
end
# Handle valued break (break name val)
if numchildren(ex) >= 2
Expand Down
17 changes: 17 additions & 0 deletions JuliaLowering/test/branching_ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,20 @@ x = @label foo
LoweringError:
x = @label foo
# └─┘ ── misplaced label in value position

########################################
# Labeled block with underscore label and valued break
@label _ begin
a
break _ 42
b
end
#---------------------
1 (= slot₁/__result core.nothing)
2 TestMod.a
3 (= slot₁/__result 42)
4 (goto label₇)
5 TestMod.b
6 (= slot₁/__result %₅)
7 slot₁/__result
8 (return %₇)
4 changes: 2 additions & 2 deletions JuliaLowering/test/loops_ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ break
#---------------------
LoweringError:
break
└───┘ ── break must be used inside a `while` or `for` loop
└───┘ ── `break` must be used inside a `while` or `for` loop

########################################
# Error: continue outside for/while
continue
#---------------------
LoweringError:
continue
└──────┘ ── continue must be used inside a `while` or `for` loop
└──────┘ ── `continue` must be used inside a `while` or `for` loop

########################################
# Error: `outer` without outer local variable
Expand Down
5 changes: 4 additions & 1 deletion src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -5069,7 +5069,10 @@ f(x) = yt(x)
((break)
(let ((labl (assq (cadr e) break-labels)))
(if (not labl)
(error "break or continue outside loop")
(let ((name (cadr e)))
(if (memq name '(loop-exit loop-cont))
(error "break or continue outside loop")
(error (string "`break " name "` not in a block with label `" name "`"))))
(begin
;; Check if this is a valued break (break name val)
(if (length> e 2)
Expand Down