Skip to content

Conversation

@oinoom
Copy link
Contributor

@oinoom oinoom commented Nov 21, 2025

pprust can emit "" for statements containing DUMMY_NODE_ID locals. When the rewrite pipeline reparses that text, it yields zero statements and trips the lone() assertion, crashing sink_lets and remove_redundant_let_types.

  • those transforms now set the new statement’s span to the original local’s span so source recovery has a real location instead of DUMMY_SP
  • rewrite_at_impl adds a fallback: if pprust pretty-printing returns an empty string (seen for DUMMY_NODE_ID locals), it pulls the original source via span_to_snippet before reparsing
  • span preservation was also added to related rewrites (fold_let_assign and remove_redundant_let_types) so replacements keep usable spans

Copy link
Contributor

@kkysen kkysen left a comment

Choose a reason for hiding this comment

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

Mostly LGTM, but I'm not super familiar with the code, so probably wait for Andrei to review, too.

Transforms that create new statement wrappers need to preserve source spans
for the rewrite system to extract text during recovery.

Changes:
- Set stmt.span explicitly in transforms when wrapping locals
- Extend Splice for Stmt to include attributes from inner nodes
- Add fallback in rewrite_at_impl for macro-expanded code

Fixes sink_lets and remove_redundant_let_types on libxml2.
//
// If the printed text is empty, try extracting the source directly using
// splice_span() (which includes attributes). If source is available, use that
// for reparsing instead of the empty pretty-printed text.
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this reinsert back code that the transforms decided to delete?

self.span
// Extend statement span to include attributes on the inner node.
//
// Transforms like sink_lets set stmt.span = local.span, but attributes are
Copy link
Contributor

Choose a reason for hiding this comment

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

You're fixing sink_lets below, is this also needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My understanding is that the attributes need to sink as well, without this the extracted source code span would just be the let statement but with this we cover the attribute as well and so we'll get a match to the pretty printed code (which includes the attribute)

Copy link
Contributor

Choose a reason for hiding this comment

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

We create a bunch of new mk()...local_stmt(...) below, couldn't we copy the attributes there?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not exactly sure how that would be done, can you put attributes inside a statement? I thought that was contained at a higher level.

Copy link
Contributor

Choose a reason for hiding this comment

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

You can put attributes on a statement, wouldn't that work here?

@oinoom oinoom changed the title refactor: fix statement span handling in transforms refactor: preserve spans for rewrites and add empty-print fallback to avoid sink_lets crash Nov 22, 2025
@oinoom oinoom changed the title refactor: preserve spans for rewrites and add empty-print fallback to avoid sink_lets crash refactor: preserve spans for rewrites and add empty-print fallback to avoid sink_lets and remove_redundant_let_types Nov 22, 2025
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.

4 participants