Skip to content

Support throwing native values and re-throwing - #943

Open
jeaye wants to merge 4 commits into
mainfrom
native-throw
Open

Support throwing native values and re-throwing#943
jeaye wants to merge 4 commits into
mainfrom
native-throw

Conversation

@jeaye

@jeaye jeaye commented Aug 6, 2026

Copy link
Copy Markdown
Member

No description provided.

@jeaye
jeaye requested a lite review from Copilot August 6, 2026 16:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR extends throw handling to support rethrowing with no value and to preserve/propagate thrown value type information through IR, evaluation, and C++ codegen (including native C++ thrown values).

Changes:

  • Allow (throw) (no argument) and represent throw values as optional + typed in analysis/IR.
  • Update IR rewrite/walk/print and codegen paths to handle optional throw values and native types.
  • Add new throw-related tests (rethrow + native value throw/catch, including constructor edge cases).

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
compiler+runtime/test/jank/form/try/pass-finally-behavior.jank Adjusts throw expression in existing finally-behavior test.
compiler+runtime/test/jank/form/throw/fail-no-value.jank Removes previous “fail” test for (throw) now that it’s supported.
compiler+runtime/test/jank/cpp/throw/pass-rethrow.jank Adds coverage for rethrowing from an inner catch.
compiler+runtime/test/jank/cpp/throw/pass-native-value.jank Adds coverage for throwing/catching a native C++ type.
compiler+runtime/test/jank/cpp/throw/pass-native-value-no-move-ctor.jank Tests throwing a type without a move ctor (copy semantics).
compiler+runtime/test/jank/cpp/throw/pass-native-value-no-copy-ctor.jank Tests throwing a move-only type.
compiler+runtime/test/jank/cpp/throw/pass-native-value-deleted-copy-ctor-default-move-ctor.jank Tests throwing a type with deleted copy + defaulted move.
compiler+runtime/test/jank/cpp/throw/fail-native-value-deleted-move-ctor.jank Introduces a “fail” case for deleted move ctor.
compiler+runtime/test/jank/cpp/throw/fail-native-value-deleted-copy-ctor-deleted-move-ctor.jank Introduces a “fail” case for deleted copy + deleted move.
compiler+runtime/src/cpp/jank/ir/walk.cpp Updates reference walking for optional typed throw values.
compiler+runtime/src/cpp/jank/ir/rewrite.cpp Updates identifier rewriting for optional typed throw values.
compiler+runtime/src/cpp/jank/ir/processor.cpp Emits IR for (throw) vs (throw v) and threads value type.
compiler+runtime/src/cpp/jank/ir/print.cpp Prints throw inst with optional value and value type.
compiler+runtime/src/cpp/jank/ir/instruction.cpp Splits throw inst constructors into “no value” and “typed value” forms.
compiler+runtime/src/cpp/jank/ir/builder.cpp Adds builder::throw_() and builder::throw_(value, type) overloads.
compiler+runtime/src/cpp/jank/evaluate.cpp Updates evaluator walk/eval behavior for optional throw value.
compiler+runtime/src/cpp/jank/codegen/cpp_processor.cpp Adds codegen for typed throws and (throw) rethrow.
compiler+runtime/src/cpp/jank/analyze/processor.cpp Allows 0 or 1 args to throw and adds C++ ctor legality checks for thrown values.
compiler+runtime/src/cpp/jank/analyze/expr/throw.cpp Adds no-value throw ctor; updates walk/to_runtime_data for optional value.
compiler+runtime/include/cpp/jank/ir/instruction.hpp Changes throw inst value to option<typed_identifier> and updates ctors.
compiler+runtime/include/cpp/jank/ir/builder.hpp Updates builder API for throw with/without value.
compiler+runtime/include/cpp/jank/analyze/expr/throw.hpp Changes throw expr value to optional and adds no-value ctor.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +575 to +582
if(expr->value.is_some())
{
throw eval(expr->value.unwrap());
}
else
{
throw;
}
Comment on lines +1044 to +1047
else
{
util::format_to(b.body_buffer, "throw;\n");
}
Comment on lines +28 to +34
object_ref v;
if(value.is_some())
{
v = jank::detail::to_runtime_data(*value.unwrap());
}
return merge(expression::to_runtime_data(),
obj::persistent_array_map::create_unique(make_box("value"),
jank::detail::to_runtime_data(*value)));
obj::persistent_array_map::create_unique(make_box("value"), v));
if(3 <= o->count())
{
return error::analyze_invalid_throw("'throw' requires exactly one argument.",
return error::analyze_invalid_throw("'throw' requires exactly zero or one arguments.",
Comment on lines +17 to +22
(try
(let* [f (cpp/jank.cpp.throw_.fail_native_value_deleted_move_ctor.foo 5)]
(throw f))
(catch jank.cpp.throw_.fail_native_value_deleted_move_ctor.foo f
(if (= 5 (.-a f))
:success)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants