-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Use rust idioms for accessing a Vec in codegen/src/compile.rs
#6326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughReplaced direct indexing and panic-prone accesses on the symbol-table stack in Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
crates/codegen/src/compile.rs (2)
609-630: Avoidunsafe+unwrap_unchecked()in push_symbol_tableThe invariant (“we just pushed, so it can't be empty”) is correct, but
unsafe { last().unwrap_unchecked() }is unnecessary here and makes the code harder to audit. A safe version is just as concise and keeps the same “compiler bug” semantics:- self.symbol_table_stack.push(table); - // SAFETY: We just pushed, so it can't be empty - unsafe { &self.symbol_table_stack.last().unwrap_unchecked() } + self.symbol_table_stack.push(table); + self.symbol_table_stack + .last() + .expect("symbol_table_stack is empty after push! This is a compiler bug.")This also matches the style used in
current_symbol_table().
1192-1210: Make TypeParams parent lookup avoidlen() - 2underflowIn the TypeParams special case, the parent table is fetched via:
self.symbol_table_stack .get(self.symbol_table_stack.len() - 2) .expect("Symbol has no parent! This is a compiler bug.") .lookup(name.as_ref())Given current invariants,
len() >= 2wheneveris_typeparamsis true, but if that invariant is ever broken, the code will panic earlier with anattempt to subtract with overflowinstead of the intended “compiler bug” message.You can keep the same semantics while avoiding this sharp edge and using more idiomatic traversal:
- let symbol = if symbol.is_none() && is_typeparams { - self.symbol_table_stack - .get(self.symbol_table_stack.len() - 2) // Try to get parent index - .expect("Symbol has no parent! This is a compiler bug.") - .lookup(name.as_ref()) - } else { - symbol - }; + let symbol = if symbol.is_none() && is_typeparams { + let parent = self + .symbol_table_stack + .iter() + .rev() + .nth(1) + .expect("Symbol has no parent! This is a compiler bug."); + parent.lookup(name.as_ref()) + } else { + symbol + };This keeps the “compiler bug” panic but removes the intermediate
len() - 2arithmetic.
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
crates/codegen/src/compile.rs(4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.rs: Follow the default rustfmt code style by runningcargo fmtto format Rust code
Always run clippy to lint Rust code (cargo clippy) before completing tasks and fix any warnings or lints introduced by changes
Follow Rust best practices for error handling and memory management
Use the macro system (pyclass,pymodule,pyfunction, etc.) when implementing Python functionality in Rust
Files:
crates/codegen/src/compile.rs
🧠 Learnings (1)
📚 Learning: 2025-11-29T12:17:28.606Z
Learnt from: CR
Repo: RustPython/RustPython PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T12:17:28.606Z
Learning: Applies to **/*.rs : Follow Rust best practices for error handling and memory management
Applied to files:
crates/codegen/src/compile.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: Ensure compilation on various targets
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
- GitHub Check: Check the WASM package and demo
- GitHub Check: Run snippets and cpython tests on wasm-wasi
- GitHub Check: Run snippets and cpython tests (windows-latest)
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Run rust tests (windows-latest)
- GitHub Check: Check Rust code with clippy
- GitHub Check: Run tests under miri
🔇 Additional comments (2)
crates/codegen/src/compile.rs (2)
558-563: current_symbol_table now uses idiomatic Vec::last accessUsing
symbol_table_stack.last().expect(...)is clearer and avoids manual indexing while still treating an empty stack as an internal compiler bug. No issues here.
657-665: enter_scope symbol-table lookup now uses Vec::get safelySwitching from manual index-based access to
self.symbol_table_stack.get(key)with an explicitSyntaxError("unknown symbol table entry")onNoneis a good, idiomatic improvement and keeps out-of-bounds conditions from turning into generic panics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
crates/codegen/src/compile.rs (2)
612-629: Avoidunsafe/unwrap_uncheckedinpush_symbol_tableThe
unwrap_uncheckedhere is correct under the stated invariant, but it introducesunsafefor a very small gain. Since this isn’t an ultra‑hot path and the stack cannot be empty afterpush, you can keep the code safe and aligned with the PR’s intent (idiomaticVecaccess) by reusingcurrent_symbol_tableinstead ofunsafe:let table = current_table.sub_tables.remove(0); // Push the next table onto the stack self.symbol_table_stack.push(table); - // SAFETY: We just pushed, so it can't be empty - unsafe { self.symbol_table_stack.last().unwrap_unchecked() } + self.current_symbol_table()This preserves behavior, removes
unsafe, and keeps allVecaccess in one helper. As per coding guidelines, safer patterns are preferred when possible.
1193-1204: Make parent lookup in TypeParams scope avoidlen() - 2arithmeticThe TypeParams parent lookup now uses
Vec::get(self.symbol_table_stack.len() - 2).expect(...). Logically this matches the existing invariant (“there must be a parent”), butlen() - 2can underflow in debug builds if that invariant is ever broken, yielding a less helpful panic than your customexpectmessage.You can stay within the “idiomatic Vec access” goal and avoid manual index math by using an iterator from the back to get “the element before last”:
- // If not found and we're in TypeParams scope, try parent scope - let symbol = if symbol.is_none() && is_typeparams { - self.symbol_table_stack - .get(self.symbol_table_stack.len() - 2) // Try to get parent index - .expect("Symbol has no parent! This is a compiler bug.") - .lookup(name.as_ref()) - } else { - symbol - }; + // If not found and we're in TypeParams scope, try parent scope + let symbol = if symbol.is_none() && is_typeparams { + let parent = self + .symbol_table_stack + .iter() + .rev() + .nth(1) // second-from-last element is the parent + .expect("Symbol has no parent! This is a compiler bug."); + parent.lookup(name.as_ref()) + } else { + symbol + };This keeps the same invariant but avoids explicit
len() - 2arithmetic on theVec.
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
crates/codegen/src/compile.rs(4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.rs: Follow the default rustfmt code style by runningcargo fmtto format Rust code
Always run clippy to lint Rust code (cargo clippy) before completing tasks and fix any warnings or lints introduced by changes
Follow Rust best practices for error handling and memory management
Use the macro system (pyclass,pymodule,pyfunction, etc.) when implementing Python functionality in Rust
Files:
crates/codegen/src/compile.rs
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: RustPython/RustPython PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T12:17:28.606Z
Learning: Applies to **/*.rs : Follow Rust best practices for error handling and memory management
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: Run snippets and cpython tests on wasm-wasi
- GitHub Check: Check the WASM package and demo
- GitHub Check: Check Rust code with clippy
- GitHub Check: Run tests under miri
- GitHub Check: Run snippets and cpython tests (windows-latest)
- GitHub Check: Ensure compilation on various targets
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Run rust tests (windows-latest)
- GitHub Check: Run rust tests (macos-latest)
- GitHub Check: Run rust tests (ubuntu-latest)
🔇 Additional comments (2)
crates/codegen/src/compile.rs (2)
560-562:current_symbol_tablenow usesVec::lastwith a clear invariantUsing
.last().expect("symbol_table_stack is empty! ...")is an idiomatic way to express the internal invariant and avoids manual indexing. Looks good.
658-664: Guardedenter_scopesymbol-table lookup is clear and safeSwitching from direct indexing to
self.symbol_table_stack.get(key)with an explicitSyntaxError("unknown symbol table entry")onNonemakes this more robust and self-documenting, while keeping the invariant that callers must pass a valid key. No issues here.
youknowone
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.