Skip to content

Commit

Permalink
Rollup merge of rust-lang#133784 - dtolnay:visitspans, r=compiler-errors
Browse files Browse the repository at this point in the history
Fix MutVisitor's default implementations to visit Stmt's and BinOp's spans

The `Stmt` case is a bug introduced almost certainly unintentionally by rust-lang#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
  }
```
  • Loading branch information
matthiaskrgr authored Dec 4, 2024
2 parents afffc1a + a3cfe2f commit 45088fd
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 22 deletions.
16 changes: 9 additions & 7 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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
}

Expand Down
16 changes: 1 addition & 15 deletions tests/ui-fulldeps/pprust-parenthesis-insertion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -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>> {
Expand Down

0 comments on commit 45088fd

Please sign in to comment.