diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-12-04 05:42:08 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-04 05:42:08 +0100 |
| commit | 45088fdf68b3a9b6e68c736f9e1cf4ee933fa46a (patch) | |
| tree | 8d38364077cc901e29f34428fbbd16a4c7e0753a | |
| parent | afffc1a86557e0981902dafb04b9332932e08e9c (diff) | |
| parent | a3cfe2fd083408b53fa02a90af718b49d2bbe83a (diff) | |
| download | rust-45088fdf68b3a9b6e68c736f9e1cf4ee933fa46a.tar.gz rust-45088fdf68b3a9b6e68c736f9e1cf4ee933fa46a.zip | |
Rollup merge of #133784 - dtolnay:visitspans, r=compiler-errors
Fix MutVisitor's default implementations to visit Stmt's and BinOp's spans
The `Stmt` case is a bug introduced almost certainly unintentionally by https://github.com/rust-lang/rust/pull/126993. The code _used_ to visit and mutate `span` correctly, but got changed as follows by that PR. Notice how `span` is **copied** into the output by `|kind| Stmt { id, kind, span }` which happens after the mutation in the correct code (red) and before the mutation in the incorrect code (green).
```diff
pub fn noop_flat_map_stmt<T: MutVisitor>(
Stmt { kind, mut span, mut id }: Stmt,
vis: &mut T,
) -> SmallVec<[Stmt; 1]> {
vis.visit_id(&mut id);
- vis.visit_span(&mut span);
let stmts: SmallVec<_> = noop_flat_map_stmt_kind(kind, vis)
.into_iter()
.map(|kind| Stmt { id, kind, span })
.collect();
if stmts.len() > 1 {
panic!(...);
}
+ vis.visit_span(&mut span);
stmts
}
```
| -rw-r--r-- | compiler/rustc_ast/src/mut_visit.rs | 16 | ||||
| -rw-r--r-- | tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 16 |
2 files changed, 10 insertions, 22 deletions
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 196fcc1af30..622c260868e 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1625,9 +1625,10 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token visit_thin_exprs(vis, call_args); vis.visit_span(span); } - ExprKind::Binary(_binop, lhs, rhs) => { + ExprKind::Binary(binop, lhs, rhs) => { vis.visit_expr(lhs); vis.visit_expr(rhs); + vis.visit_span(&mut binop.span); } ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), ExprKind::Cast(expr, ty) => { @@ -1785,20 +1786,21 @@ pub fn noop_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Optio pub fn walk_flat_map_stmt<T: MutVisitor>( vis: &mut T, - Stmt { kind, mut span, mut id }: Stmt, + Stmt { kind, span, mut id }: Stmt, ) -> SmallVec<[Stmt; 1]> { vis.visit_id(&mut id); - let stmts: SmallVec<_> = walk_flat_map_stmt_kind(vis, kind) + let mut stmts: SmallVec<[Stmt; 1]> = walk_flat_map_stmt_kind(vis, kind) .into_iter() .map(|kind| Stmt { id, kind, span }) .collect(); - if stmts.len() > 1 { - panic!( + match stmts.len() { + 0 => {} + 1 => vis.visit_span(&mut stmts[0].span), + 2.. => panic!( "cloning statement `NodeId`s is prohibited by default, \ the visitor should implement custom statement visiting" - ); + ), } - vis.visit_span(&mut span); stmts } diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index fd6644d73c1..b83e576076d 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -36,12 +36,11 @@ extern crate rustc_errors; extern crate rustc_parse; extern crate rustc_session; extern crate rustc_span; -extern crate smallvec; use std::mem; use std::process::ExitCode; -use rustc_ast::ast::{DUMMY_NODE_ID, Expr, ExprKind, Stmt}; +use rustc_ast::ast::{DUMMY_NODE_ID, Expr, ExprKind}; use rustc_ast::mut_visit::{self, DummyAstNode as _, MutVisitor}; use rustc_ast::node_id::NodeId; use rustc_ast::ptr::P; @@ -50,7 +49,6 @@ use rustc_errors::Diag; use rustc_parse::parser::Recovery; use rustc_session::parse::ParseSess; use rustc_span::{DUMMY_SP, FileName, Span}; -use smallvec::SmallVec; // Every parenthesis in the following expressions is re-inserted by the // pretty-printer. @@ -164,18 +162,6 @@ impl MutVisitor for Normalize { fn visit_span(&mut self, span: &mut Span) { *span = DUMMY_SP; } - - fn visit_expr(&mut self, expr: &mut P<Expr>) { - if let ExprKind::Binary(binop, _left, _right) = &mut expr.kind { - self.visit_span(&mut binop.span); - } - mut_visit::walk_expr(self, expr); - } - - fn flat_map_stmt(&mut self, mut stmt: Stmt) -> SmallVec<[Stmt; 1]> { - self.visit_span(&mut stmt.span); - mut_visit::walk_flat_map_stmt(self, stmt) - } } fn parse_expr(psess: &ParseSess, source_code: &str) -> Option<P<Expr>> { |
