Skip to content

feat(logging): add SpanGuard and SPAN_GUARD macro for IR source location in errors#496

Open
luohuan19 wants to merge 1 commit intohw-native-sys:mainfrom
luohuan19:fix-issue-477
Open

feat(logging): add SpanGuard and SPAN_GUARD macro for IR source location in errors#496
luohuan19 wants to merge 1 commit intohw-native-sys:mainfrom
luohuan19:fix-issue-477

Conversation

@luohuan19
Copy link
Contributor

Introduce SpanGuard RAII class and SPAN_GUARD macro to embed IR node span information into INTERNAL_CHECK failure messages. When a check fails inside a visitor/mutator/codegen method, the error now includes the user's source location (e.g. "(at user_model.py:12:5)") before the standard check-failed line.

  • Add thread-local g_current_span_str and SpanGuard to logging.h
  • Add SPAN_GUARD(span) macro for use at the top of Visit*_ methods
  • Add internal_check_with_span() C++ helper and Python binding for explicit span-scoped checks from Python
  • Expose internal_check_with_span in Python public API and type stubs
  • Instrument Visit*_ methods in mutator, visitor, python_printer, split_chunked_loops_pass, and all three codegens with SPAN_GUARD
  • Add comprehensive tests covering valid span, unknown span, pass-through, and nested guard restoration using real @pl.program IR

closes #477

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Introduces a thread-local span context and RAII SpanGuard to attach IR source locations to InternalError messages. Adds a span-aware internal_check_with_span binding and inserts SPAN_GUARD calls across codegen and IR transform visitors to populate the context during traversal and code generation. Tests added for end-to-end behavior.

Changes

Cohort / File(s) Summary
Core Logging Infrastructure
include/pypto/core/logging.h
Adds internal namespace with inline thread_local std::string g_current_span_str, SpanGuard RAII class, SPAN_GUARD(span) macro, and updates FatalLogger to include current span in error messages.
Python Bindings
python/bindings/modules/logging.cpp
Adds internal_check_with_span(bool, const ir::Span&, const std::string&) implementation and exposes it to Python (m.def("internal_check_with_span", ...)), using SPAN_GUARD to embed span during checks.
Python Module Exports & Stubs
python/pypto/__init__.py, python/pypto/pypto_core/__init__.pyi, python/pypto/pypto_core/logging.pyi
Re-exports internal_check_with_span in the public Python package and updates type stubs and all to include the new function and its signature.
Codegen Span Guards
src/codegen/cce/cce_codegen.cpp, src/codegen/orchestration/orchestration_codegen.cpp, src/codegen/pto/pto_codegen.cpp
Inserts SPAN_GUARD(op->span_) at entry points of many IR visitors/emitters (AssignStmt, EvalStmt, ReturnStmt, YieldStmt, IfStmt, ForStmt, expressions, operators) to set span context during code generation.
IR Transform & Visitor Span Guards
src/ir/transforms/mutator.cpp, src/ir/transforms/visitor.cpp, src/ir/transforms/python_printer.cpp, src/ir/transforms/split_chunked_loops_pass.cpp
Adds SPAN_GUARD(op->span_) at starts of various visitor/mutator methods (IterArg, Call, ForStmt, Cast, etc.) and printing hooks to propagate span context during traversal and transforms.
Tests
tests/ut/core/test_logging.py
Adds comprehensive tests exercising internal_check_with_span, span formatting, unknown-span behavior, IR-derived spans from @pl.program, and nested SpanGuard restoration semantics.

Sequence Diagram(s)

sequenceDiagram
    participant IR as IR Node Visitor
    participant SpanGuard as SpanGuard (thread-local)
    participant Code as Codegen / Transform
    participant Logger as FatalLogger / InternalError
    participant Python as Python Binding

    IR->>SpanGuard: SPAN_GUARD(op->span_)  (set g_current_span_str)
    IR->>Code: perform visitor / emit work
    Code->>Logger: INTERNAL_CHECK fails
    Logger->>SpanGuard: read g_current_span_str
    Logger->>Python: raise InternalError with "(at file:line:col)" appended
    SpanGuard-->>IR: destructor restores previous span (scope exit)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 I tuck a span in thread-local fur,
Guarding each visit with a gentle purr,
When checks go awry and errors demand,
I point to the line with a twitch of my hand,
Hop—now your bug trace is easy to spurr. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: introducing SpanGuard RAII class and SPAN_GUARD macro to embed IR source location in error messages.
Description check ✅ Passed The description is detailed and directly related to the changeset, explaining the feature, implementation approach, and listing the files modified.
Linked Issues check ✅ Passed The PR implementation aligns with issue #477 objectives: introduces thread-local span context via SpanGuard/SPAN_GUARD macro, adds internal_check_with_span binding, instruments visitor/mutator/codegen methods, and provides comprehensive tests covering valid/unknown spans.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing span-aware error reporting: adding logging infrastructure, Python bindings, and systematically instrumenting visitor/mutator/codegen methods with SPAN_GUARD as intended.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances debugging capabilities by integrating IR node source location information directly into internal error messages. By introducing a thread-local span context managed by an RAII guard, developers can now pinpoint the exact user code location that led to an internal check failure, drastically improving the clarity and actionability of error reports. This change provides a more robust and user-friendly error reporting mechanism without altering the core logic of the system.

Highlights

  • Enhanced Error Reporting: Introduced SpanGuard RAII class and SPAN_GUARD macro to embed IR node source location information directly into INTERNAL_CHECK failure messages, providing more precise debugging context.
  • Core Logging Integration: Modified FatalLogger to automatically include the current thread-local span string in error messages, ensuring user-friendly source location details are present when checks fail.
  • Python API Extension: Added a new internal_check_with_span C++ helper function and exposed it to the Python API, allowing explicit span-scoped checks from Python code.
  • Widespread Instrumentation: Instrumented numerous Visit*_ methods across codegens (CCE, Orchestration, PTO), IR mutators, visitors, and Python printers with SPAN_GUARD to automatically capture and propagate IR node spans.
  • Comprehensive Testing: Included extensive unit tests covering valid and unknown spans, pass-through behavior, and correct restoration of nested SpanGuard contexts, utilizing real @pl.program IR to validate end-to-end functionality.
Changelog
  • include/pypto/core/logging.h
    • Added g_current_span_str thread-local variable for span context.
    • Modified FatalLogger to include span information in error messages.
    • Introduced SpanGuard RAII class for managing span context.
    • Defined SPAN_GUARD macro for easy span context application.
  • python/bindings/modules/logging.cpp
    • Added internal_check_with_span C++ function.
    • Exposed internal_check_with_span to the Python API.
  • python/pypto/init.py
    • Exported internal_check_with_span for Python users.
  • python/pypto/pypto_core/init.pyi
    • Updated type stubs to include internal_check_with_span.
  • python/pypto/pypto_core/logging.pyi
    • Imported ir.
    • Added type stub for internal_check_with_span.
  • src/codegen/cce/cce_codegen.cpp
    • Applied SPAN_GUARD to various VisitStmt_ and VisitExpr_ methods.
  • src/codegen/orchestration/orchestration_codegen.cpp
    • Applied SPAN_GUARD to VisitStmt_ methods for ForStmt, AssignStmt, and EvalStmt.
  • src/codegen/pto/pto_codegen.cpp
    • Applied SPAN_GUARD to VisitStmt_ methods for EvalStmt, YieldStmt, IfStmt, and ForStmt.
  • src/ir/transforms/mutator.cpp
    • Applied SPAN_GUARD to VisitExpr_ methods for IterArg and Call, and VisitStmt_ for ForStmt.
  • src/ir/transforms/python_printer.cpp
    • Applied SPAN_GUARD to VisitExpr_ methods for Call and Cast, VisitStmt_ for ForStmt and ScopeStmt.
    • Applied SPAN_GUARD to VisitExpr_(const CallPtr&) within GlobalVarCollector.
  • src/ir/transforms/split_chunked_loops_pass.cpp
    • Applied SPAN_GUARD to VisitStmt_(const ForStmtPtr&).
  • src/ir/transforms/visitor.cpp
    • Applied SPAN_GUARD to VisitExpr_ methods for IterArg and Call, and VisitStmt_ for ForStmt.
  • tests/ut/core/test_logging.py
    • Added unit tests for internal_check_with_span functionality and SpanGuard behavior with real IR programs.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (1)
tests/ut/core/test_logging.py (1)

624-653: Test name slightly misrepresents the behavior being tested.

The test test_nested_span_guard_restores_outer_span tests sequential internal_check_with_span calls rather than truly nested RAII guards. Each call creates and immediately destroys its own SpanGuard. A true nested test would require C++ code where one SPAN_GUARD is active while another is created inside it.

The test is still valuable for verifying that sequential calls don't leak span context, which is the actual behavior being validated. Consider renaming to test_sequential_span_checks_isolate_context or updating the docstring to clarify the sequential nature.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/ut/core/test_logging.py` around lines 624 - 653, Rename the test
function test_nested_span_guard_restores_outer_span to
test_sequential_span_checks_isolate_context (or update its docstring) to
accurately reflect that it exercises sequential internal_check_with_span calls
that set and clear SpanGuard context rather than true nested RAII guards; update
the function name and/or the triple-quoted docstring at the top of the test to
mention that it verifies sequential creation/destruction of SpanGuard via
pypto.internal_check_with_span and that pypto.internal_check has no span
afterwards, referencing symbols internal_check_with_span, internal_check, and
SpanGuard in the docstring to make intent explicit.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/codegen/orchestration/orchestration_codegen.cpp`:
- Around line 547-548: The IfStmt visitor is missing a span scope so errors
during condition generation or traversing a top-level if lack source location;
add a SPAN_GUARD(if_stmt->span_) at the start of VisitStmt_(const IfStmtPtr&
if_stmt) to mirror other statement visitors, and likewise add SPAN_GUARD(...) to
the other unguarded statement visitors referenced (the neighboring visitors
around the same block) to ensure all statement paths are wrapped with the span
guard.

In `@src/codegen/pto/pto_codegen.cpp`:
- Around line 1054-1055: The AssignStmt visitor lacks span guarding so errors
during lowering lose user locations; add SPAN_GUARD(op->span_) as the first
statement in VisitStmt_(const AssignStmtPtr& op) to ensure any
CHECK/INTERNAL_CHECK reports the assignment span, and likewise add the same
SPAN_GUARD(op->span_) to the other unguarded VisitStmt_ overloads referenced
(the other VisitStmt_(...) functions missing guards) so all hot-path statement
lowering uses the span guard.

In `@src/ir/transforms/mutator.cpp`:
- Around line 49-50: The mutator currently only installs SPAN_GUARD in a few
overloads (e.g., IterArg, Call, ForStmt), leaving many INTERNAL_CHECK failures
outside the correct span; update the mutator to install the span guard at every
visitor entry so failures report the node's span: either add
SPAN_GUARD(op->span_) to the remaining VisitExpr_/VisitStmt_ overloads (e.g.,
AssignStmt, IfStmt, MakeTuple, TupleGetItemExpr and the binary/unary operator
visitors) or centralize the guard by adding it to the common dispatch entry used
by ExprFunctor/StmtFunctor before delegating to specific VisitExpr_/VisitStmt_
methods (ensure VisitExpr_/VisitStmt_ signatures such as
IRMutator::VisitExpr_(const XPtr& op) and IRMutator::VisitStmt_(const YPtr& op)
all run SPAN_GUARD with op->span_).

In `@src/ir/transforms/visitor.cpp`:
- Around line 41-42: The visitor only guards a few overloads (e.g.,
VisitExpr_(IterArgPtr)) which leaves many other nodes calling INTERNAL_CHECK
without a current span; instead, add span propagation at the central recursion
entry points by placing the SPAN_GUARD (or equivalent span-setting logic) at
IRVisitor::VisitExpr and IRVisitor::VisitStmt so every recursive dispatch sets
the current span before calling any VisitExpr_/VisitStmt_ overloads (this will
cover MakeTuple, TupleGetItemExpr, unary/binary visitors, AssignStmt, IfStmt,
YieldStmt, ReturnStmt, WhileStmt and container statements); update or remove
redundant per-overload SPAN_GUARDs (e.g., the ones at the three existing
overloads and lines mentioned) to avoid duplication and ensure INTERNAL_CHECK
always sees a valid span.

In `@tests/ut/core/test_logging.py`:
- Around line 619-622: The f-string assertion in the test (assert start_line <=
for_stmt.span.begin_line <= func_end_line) contains an en-dash character in the
message f"...(lines {start_line}–{func_end_line})"; replace that en-dash with a
standard hyphen-minus so the message becomes f"...(lines
{start_line}-{func_end_line})" to eliminate the ambiguous character while
keeping the same formatting and variables (start_line, for_stmt.span.begin_line,
func_end_line).

---

Nitpick comments:
In `@tests/ut/core/test_logging.py`:
- Around line 624-653: Rename the test function
test_nested_span_guard_restores_outer_span to
test_sequential_span_checks_isolate_context (or update its docstring) to
accurately reflect that it exercises sequential internal_check_with_span calls
that set and clear SpanGuard context rather than true nested RAII guards; update
the function name and/or the triple-quoted docstring at the top of the test to
mention that it verifies sequential creation/destruction of SpanGuard via
pypto.internal_check_with_span and that pypto.internal_check has no span
afterwards, referencing symbols internal_check_with_span, internal_check, and
SpanGuard in the docstring to make intent explicit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 457e3c16-3089-4dc2-af79-6f25788b19e8

📥 Commits

Reviewing files that changed from the base of the PR and between bab76b2 and 8ee7708.

📒 Files selected for processing (13)
  • include/pypto/core/logging.h
  • python/bindings/modules/logging.cpp
  • python/pypto/__init__.py
  • python/pypto/pypto_core/__init__.pyi
  • python/pypto/pypto_core/logging.pyi
  • src/codegen/cce/cce_codegen.cpp
  • src/codegen/orchestration/orchestration_codegen.cpp
  • src/codegen/pto/pto_codegen.cpp
  • src/ir/transforms/mutator.cpp
  • src/ir/transforms/python_printer.cpp
  • src/ir/transforms/split_chunked_loops_pass.cpp
  • src/ir/transforms/visitor.cpp
  • tests/ut/core/test_logging.py

Comment on lines 547 to +548
void VisitStmt_(const ForStmtPtr& for_stmt) override {
SPAN_GUARD(for_stmt->span_);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

IfStmt is the remaining unguarded statement path here.

VisitStmt_(const IfStmtPtr& if_stmt) at Lines 594-639 still runs without a span scope, so failures while generating the condition or traversing a top-level if will produce an error without the source location even though the neighboring statement visitors now do.

Minimal fix
 void VisitStmt_(const IfStmtPtr& if_stmt) override {
+  SPAN_GUARD(if_stmt->span_);
   std::string cond_expr = GenerateExprString(if_stmt->condition_);

Also applies to: 641-642, 691-692

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/codegen/orchestration/orchestration_codegen.cpp` around lines 547 - 548,
The IfStmt visitor is missing a span scope so errors during condition generation
or traversing a top-level if lack source location; add a
SPAN_GUARD(if_stmt->span_) at the start of VisitStmt_(const IfStmtPtr& if_stmt)
to mirror other statement visitors, and likewise add SPAN_GUARD(...) to the
other unguarded statement visitors referenced (the neighboring visitors around
the same block) to ensure all statement paths are wrapped with the span guard.

Comment on lines 1054 to +1055
void PTOCodegen::VisitStmt_(const EvalStmtPtr& op) {
SPAN_GUARD(op->span_);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

AssignStmt is still the unguarded hot path.

VisitStmt_(const AssignStmtPtr& op) at Lines 491-537 is where most PTO lowering starts, but it still lacks SPAN_GUARD. Any CHECK/INTERNAL_CHECK raised while lowering an assignment RHS will therefore miss the user location on the common codegen path.

Minimal fix
 void PTOCodegen::VisitStmt_(const AssignStmtPtr& op) {
+  SPAN_GUARD(op->span_);
   if (auto call = As<ir::Call>(op->value_)) {

Also applies to: 1061-1062, 1078-1079, 1200-1201

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/codegen/pto/pto_codegen.cpp` around lines 1054 - 1055, The AssignStmt
visitor lacks span guarding so errors during lowering lose user locations; add
SPAN_GUARD(op->span_) as the first statement in VisitStmt_(const AssignStmtPtr&
op) to ensure any CHECK/INTERNAL_CHECK reports the assignment span, and likewise
add the same SPAN_GUARD(op->span_) to the other unguarded VisitStmt_ overloads
referenced (the other VisitStmt_(...) functions missing guards) so all hot-path
statement lowering uses the span guard.

Comment on lines 49 to +50
ExprPtr IRMutator::VisitExpr_(const IterArgPtr& op) {
SPAN_GUARD(op->span_);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

This still leaves most mutator failures outside a span scope.

Only IterArg, Call, and ForStmt install a guard here, but this file still has many other INTERNAL_CHECK paths (AssignStmt, IfStmt, MakeTuple, TupleGetItemExpr, the binary/unary mutators, etc.). Because the recursion in this class goes straight through ExprFunctor/StmtFunctor, failures in those paths will still report no user location or keep the enclosing node’s span instead of the failing node’s.

Also applies to: 83-84, 337-338

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ir/transforms/mutator.cpp` around lines 49 - 50, The mutator currently
only installs SPAN_GUARD in a few overloads (e.g., IterArg, Call, ForStmt),
leaving many INTERNAL_CHECK failures outside the correct span; update the
mutator to install the span guard at every visitor entry so failures report the
node's span: either add SPAN_GUARD(op->span_) to the remaining
VisitExpr_/VisitStmt_ overloads (e.g., AssignStmt, IfStmt, MakeTuple,
TupleGetItemExpr and the binary/unary operator visitors) or centralize the guard
by adding it to the common dispatch entry used by ExprFunctor/StmtFunctor before
delegating to specific VisitExpr_/VisitStmt_ methods (ensure
VisitExpr_/VisitStmt_ signatures such as IRMutator::VisitExpr_(const XPtr& op)
and IRMutator::VisitStmt_(const YPtr& op) all run SPAN_GUARD with op->span_).

Comment on lines 41 to +42
void IRVisitor::VisitExpr_(const IterArgPtr& op) {
SPAN_GUARD(op->span_);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Three guarded overloads are not enough for visitor-wide coverage.

MakeTuple, TupleGetItemExpr, the binary/unary visitors, AssignStmt, IfStmt, YieldStmt, ReturnStmt, WhileStmt, and several container statements still call INTERNAL_CHECK without setting the current span. Since this class already recurses through VisitExpr/VisitStmt, guarding those two entry points would make span propagation consistent instead of only covering these three node kinds.

Also applies to: 71-72, 183-184

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ir/transforms/visitor.cpp` around lines 41 - 42, The visitor only guards
a few overloads (e.g., VisitExpr_(IterArgPtr)) which leaves many other nodes
calling INTERNAL_CHECK without a current span; instead, add span propagation at
the central recursion entry points by placing the SPAN_GUARD (or equivalent
span-setting logic) at IRVisitor::VisitExpr and IRVisitor::VisitStmt so every
recursive dispatch sets the current span before calling any
VisitExpr_/VisitStmt_ overloads (this will cover MakeTuple, TupleGetItemExpr,
unary/binary visitors, AssignStmt, IfStmt, YieldStmt, ReturnStmt, WhileStmt and
container statements); update or remove redundant per-overload SPAN_GUARDs
(e.g., the ones at the three existing overloads and lines mentioned) to avoid
duplication and ensure INTERNAL_CHECK always sees a valid span.

Comment on lines +619 to +622
assert start_line <= for_stmt.span.begin_line <= func_end_line, (
f"ForStmt span line {for_stmt.span.begin_line} is not within "
f"this test method (lines {start_line}–{func_end_line})"
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Replace en-dash with hyphen-minus.

The static analysis tool flagged an ambiguous en-dash character () at line 621. Use a standard hyphen-minus (-) instead for consistency.

Proposed fix
         assert start_line <= for_stmt.span.begin_line <= func_end_line, (
             f"ForStmt span line {for_stmt.span.begin_line} is not within "
-            f"this test method (lines {start_line}–{func_end_line})"
+            f"this test method (lines {start_line}-{func_end_line})"
         )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assert start_line <= for_stmt.span.begin_line <= func_end_line, (
f"ForStmt span line {for_stmt.span.begin_line} is not within "
f"this test method (lines {start_line}{func_end_line})"
)
assert start_line <= for_stmt.span.begin_line <= func_end_line, (
f"ForStmt span line {for_stmt.span.begin_line} is not within "
f"this test method (lines {start_line}-{func_end_line})"
)
🧰 Tools
🪛 Ruff (0.15.5)

[warning] 621-621: String contains ambiguous (EN DASH). Did you mean - (HYPHEN-MINUS)?

(RUF001)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/ut/core/test_logging.py` around lines 619 - 622, The f-string assertion
in the test (assert start_line <= for_stmt.span.begin_line <= func_end_line)
contains an en-dash character in the message f"...(lines
{start_line}–{func_end_line})"; replace that en-dash with a standard
hyphen-minus so the message becomes f"...(lines {start_line}-{func_end_line})"
to eliminate the ambiguous character while keeping the same formatting and
variables (start_line, for_stmt.span.begin_line, func_end_line).

…ion in errors

Introduce SpanGuard RAII class and SPAN_GUARD macro to embed IR node span
information into INTERNAL_CHECK failure messages. When a check fails inside
a visitor/mutator/codegen method, the error now includes the user's source
location (e.g. "(at user_model.py:12:5)") before the standard check-failed
line.

- Add thread-local `g_current_span_str` and `SpanGuard` to `logging.h`
- Add `SPAN_GUARD(span)` macro for use at the top of Visit*_ methods
- Add `internal_check_with_span()` C++ helper and Python binding for
  explicit span-scoped checks from Python
- Expose `internal_check_with_span` in Python public API and type stubs
- Instrument Visit*_ methods in mutator, visitor, python_printer,
  split_chunked_loops_pass, and all three codegens with SPAN_GUARD
- Add comprehensive tests covering valid span, unknown span, pass-through,
  and nested guard restoration using real @pl.program IR

closes hw-native-sys#477
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/ut/core/test_logging.py (1)

590-590: Remove debug print statement.

Line 590 contains a print(msg) that appears to be leftover debug code. It should be removed before merging.

🧹 Proposed fix
         msg = str(exc_info.value)
-        print(msg)
         assert "ForStmt has null loop_var" in msg
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/ut/core/test_logging.py` at line 590, Remove the leftover debug print
by deleting the print(msg) statement in tests/ut/core/test_logging.py (the debug
print that references msg); if you need to retain visibility for debugging use
the existing test logger or assertions instead of print, but do not leave
print(msg) in the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/ut/core/test_logging.py`:
- Line 590: Remove the leftover debug print by deleting the print(msg) statement
in tests/ut/core/test_logging.py (the debug print that references msg); if you
need to retain visibility for debugging use the existing test logger or
assertions instead of print, but do not leave print(msg) in the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 92ad138c-4ef8-4f22-bc78-4e3d4f3f6b08

📥 Commits

Reviewing files that changed from the base of the PR and between 8ee7708 and 813973d.

📒 Files selected for processing (13)
  • include/pypto/core/logging.h
  • python/bindings/modules/logging.cpp
  • python/pypto/__init__.py
  • python/pypto/pypto_core/__init__.pyi
  • python/pypto/pypto_core/logging.pyi
  • src/codegen/cce/cce_codegen.cpp
  • src/codegen/orchestration/orchestration_codegen.cpp
  • src/codegen/pto/pto_codegen.cpp
  • src/ir/transforms/mutator.cpp
  • src/ir/transforms/python_printer.cpp
  • src/ir/transforms/split_chunked_loops_pass.cpp
  • src/ir/transforms/visitor.cpp
  • tests/ut/core/test_logging.py
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/codegen/cce/cce_codegen.cpp
  • python/pypto/pypto_core/init.pyi
  • src/codegen/orchestration/orchestration_codegen.cpp
  • src/codegen/pto/pto_codegen.cpp
  • src/ir/transforms/mutator.cpp
  • src/ir/transforms/split_chunked_loops_pass.cpp

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a SpanGuard RAII class and SPAN_GUARD macro, which is a great feature for improving error diagnostics by including IR source locations in INTERNAL_CHECK failure messages. The implementation using a thread_local variable is clean and thread-safe. The feature is well-integrated throughout the codebase by instrumenting visitor and codegen methods, and the new tests, including end-to-end tests with @pl.program, are comprehensive. Overall, this is a high-quality addition to the project.

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.

[Feature] Add span information to INTERNAL_CHECK / InternalError for better error source location

1 participant