# GSoC syncup: Rewrite Rust lints to operate on frontend's HIR
Rolling agenda.
[Proposal](https://summerofcode.withgoogle.com/organizations/gnu-compiler-collection-gcc/programs/2025/proposals/details/vsCPaIwP)
## 2025-08-25
### Progres
- Writing GSoC final report
- [link to my draft report](https://hackmd.io/@rokada/S1EMl15Yxl)
- [Implement unused variable checker on HIR](https://github.com/Rust-GCC/gccrs/pull/4055)
- made the suggested changes based on your review.
- I'll squash commits and refine commit message after it is approved
- [Add derived set to collect derived nodes](https://github.com/Rust-GCC/gccrs/pull/4047)
- This PR can be merged
## 2025-08-19
### Progress
- [merged] https://github.com/Rust-GCC/gccrs/pull/4069
### Questions
- https://github.com/Rust-GCC/gccrs/pull/4055#pullrequestreview-3104657721
> it would be good if you could add a flag to enable the lints you've written and then add testcases to the testsuite
How do I add flag and add testcase?
Is that similer to what we did for nr2?
## 2025-08-11
### Progress
- Submitted PR about read-only checker
- https://github.com/Rust-GCC/gccrs/pull/4055
- Resolved conflicts of two branches
- https://github.com/Rust-GCC/gccrs/pull/3681
- https://github.com/Rust-GCC/gccrs/pull/3496
- Use a set to collect derived nodes
- https://github.com/Rust-GCC/gccrs/pull/4047
- Test for macos is failing but this is not becuse of the code I modified.
## 2025-08-04
### Progress
- [In review] https://github.com/Rust-GCC/gccrs/pull/4028
- [Done] https://github.com/Rust-GCC/gccrs/pull/4024
- [Approved] https://github.com/Rust-GCC/gccrs/pull/3881
https://github.com/Rust-GCC/gccrs/pull/3681
### Questions
- In gccrs, the unused check for static items is done in the unused variable check pass, whereas rustc performs it during the dead code check pass. Do you think gccrs should do it the same way?
### Issue (Suggestion?): Let test writers concentrate on testing one specific behavior
## 2025-07
### Readonly check on HIR
### Unused variable check on HIR
- The current pass only flags variables that are never referenced. It misses “write-then-overwrite” patterns like the one below.
```rust
fn test() ->i32 {
let mut x = 2; // the value assigned here is never read
x = 3;
x
}
```
- It marks a variable as “used” the first time it sees a read or write, without considering later overwrites.
- Possible fix: implement a liveness analysis (similar to [rustc's liveness analysis](https://github.com/rust-lang/rust/blob/master/compiler/rustc_passes/src/liveness.rs)).
- Pros: precise, scales to other data-flow checks.
- Cons: large engineering effort—need to compute GEN/KILL sets.
### Questions
- Should I implement liveness analysis like rustc does, or simply migrate current implementation to HIR?
## 2025-07-17
### Progress
#### Implementing `ReadonlyChecker` on HIR
- All of the existing test has been passed!
- However, there are still some tasks I need to work on:
- Add new tests that the old Readonly checker couldn’t catch.(e.g. [check for static items](https://github.com/Rust-GCC/gccrs/issues/3892), [check for tuples](https://github.com/Rust-GCC/gccrs/issues/3893))
### Questions
- After I finish implementing the Readonly Checker on HIR, should I delete the old Readonly Checker or keep it?
## 2025-07-07
### Progress
- Implementing `ReadonlyChecker` on HIR
- [draft PR](https://github.com/Rust-GCC/gccrs/pull/3881)
### Questions
- I don't have any question to ask.
## 2025-06-30
### Progress
- Implementing `ReadonlyChecker` on HIR
#### Strategy
- Find `AssignmentExpr`
- Get left operand of it (that is [assignee expression](https://doc.rust-lang.org/stable/reference/expressions.html#r-expr.place-value.assignee))
- Check if it is mutable or not
#### Example Code
```c++
void
ReadonlyChecker::visit (AssignmentExpr &expr)
{
Expr &lhs = expr.get_lhs ();
switch (lhs.get_expression_type ())
{
case Expr::ExprType::Path:
{
// QualifiedPathInExpression or PathInExpression
// readonly check for local variables and static variables
std::unique_ptr<Path> path = static_cast<Path>(*lhs);
switch (path.get_path_type()) {
case Path::PathType::QualifiedPathInExpression: {}
case Path::PathType::PathInExpression: {}
}
}
case Expr::ExprType::FieldAccess:
{
// readonly check for field access
}
case Expr::ExprType::ArrayIndex:
{
// readonly check for array index access
}
case Expr::ExprType::Operator:
{
// readonly check for dereferences
}
case Expr::ExprType::Tuple:
{
// readonly check for tuples of expressions
}
default:
rust_error_at (expr.get_locus (),
"cannot assign to expression of type %s",
lhs.get_expression_type ());
}
}
```
### Question
- Both `QualifiedPathInExpression` and `PathInExpression` has `Expr::ExprType::Path`. How can we distinguish between these two types of nodes?
## 2025-06-23
### Progress
- finished implementing default HIR visitor
- please review it https://github.com/Rust-GCC/gccrs/pull/3854
### Questions
- I think the `MatchArm` node should have a `get_outer_attrs` method, because it has outer attributes but no way to access them.
- `SelfParam::get_lifetime` returns a const object, but the accept_vis method for `Lifetime` is not const qualified.
- Should I add const qualified version of `accept_vis` function?
- https://github.com/Rust-GCC/gccrs/blob/1f1fefef9af07328e990a731fbb9b09989cb74c8/gcc/rust/hir/tree/rust-hir-item.h#L403
## 2025-06-16
### Progress
- continue to implement default HIR visitor class
- about 60% done!
- https://github.com/sakupan102/gccrs/pull/1/files
- As previously scheduled, I have to finish implementing it by the end of this week.
### Questions
- Should I visit inner or outer attributes?
- attributes are belongs to AST, so I don't think this should be visited
- Should I visit `StructBase` nodes?
- this type of node doesn't have `accept_vis` function, but Default AST vistor visits `StructBase` nodes.
## 2025-06-09
### Progress
- [WIP] Implementing default HIR visitor class
- https://github.com/sakupan102/gccrs/pull/1/files
### Questions
- Do you think it's better to create individual feature branches directly from the master branch, rather than creating a project branch and then creating feature branches from that?
- Some types of nodes have an accept_vis function, but others don't. What is the difference?
Do you think all types of nodes need to have an accept_vis function?
- e.g. `PathIdentSegment` class does not have `accept_vis` function https://github.com/Rust-GCC/gccrs/blob/b037a1b1bcd00800612ea3a06017d2ac09a9fe10/gcc/rust/hir/tree/rust-hir-path.h#L32-L57
### Links
- [DefaultASTVisitor class](https://github.com/Rust-GCC/gccrs/blob/c8153f98c993f75263a278648e89ce99ceea4085/gcc/rust/ast/rust-ast-visitor.h#L244)
- [DefaultASTVisitor implementation](https://github.com/Rust-GCC/gccrs/blob/c8153f98c993f75263a278648e89ce99ceea4085/gcc/rust/ast/rust-ast-visitor.cc#L34)
These template functions can also be quite helpful for you:
```c++
template <typename T> void visit (T &node) { node.accept_vis (*this); }
template <typename T> void visit (std::unique_ptr<T> &node)
{
node->accept_vis (*this);
}
```
__Actions__:
- Ryutaro to continue DefaultHIRVisitor implementation for next week
## 2025-06-01
- Introduction
__Actions__:
- Ryutaro to write down questions if you have any :D
- Arthur to setup a groupchat for PE and Ryutaro