Skip to content

Conversation

@asukaminato0721
Copy link
Contributor

@asukaminato0721 asukaminato0721 commented Dec 19, 2025

fix #19168

now tags every Fragment::Tokens with a TokensOrigin (raw token vs parsed AST) so we can keep track of which fragments need to stay wrapped as a single tt chunk during transcription.

records that ty/pat/pat_param/stmt/block/meta/item/vis metavars originate from AST parses while ident/tt/lifetime/literal stay raw, so bindings carry the right origin metadata from the moment they’re matched.

respects the new origin flag: ${concat} handling destructures the updated variant, and expand_var now leaves AST-derived fragments enclosed (preventing the stray 'static token that used to cause expected Expr), while raw fragments keep the previous strip-logic.

add test

test case
@asukaminato0721 asukaminato0721 marked this pull request as ready for review December 19, 2025 20:10
Copilot AI review requested due to automatic review settings December 19, 2025 20:10
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 19, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a macro expansion bug (#19168) where AST-parsed metavariable fragments (like $t:ty) were being incorrectly stripped of invisible delimiters during transcription, causing individual tokens (e.g., 'static) to leak out and trigger "expected Expr" errors.

Key Changes:

  • Introduced TokensOrigin enum to distinguish between raw token fragments and AST-parsed fragments
  • Updated Fragment::Tokens from a tuple variant to a struct variant with an origin field
  • Modified matcher logic to tag fragments with appropriate origin during matching
  • Updated transcriber to respect origin metadata and skip stripping invisible delimiters for AST-derived fragments

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
crates/mbe/src/expander.rs Adds TokensOrigin enum and converts Fragment::Tokens to struct variant with origin tracking
crates/mbe/src/expander/matcher.rs Tags matched fragments with appropriate origin (Raw for ident/tt/lifetime/literal, Ast for ty/pat/stmt/block/meta/item/vis)
crates/mbe/src/expander/transcriber.rs Conditionally applies strip_invisible() based on fragment origin during expansion
crates/hir-def/src/macro_expansion_tests/mbe/regression.rs Adds regression test for ty fragment transcription preserving structure

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +170 to +174
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum TokensOrigin {
Raw,
Ast,
}
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

The TokensOrigin enum should have documentation explaining the distinction between Raw and Ast variants. Consider adding a doc comment like:

/// Tracks whether token fragments come from raw tokens or parsed AST.
/// This distinction is important during transcription: AST-derived fragments
/// should not have their invisible delimiters stripped to preserve their
/// structure as complete syntactic units.

This would help future maintainers understand the purpose of this enum and when to use each variant.

Copilot uses AI. Check for mistakes.
Comment on lines 130 to +134
/// token fragments are just copy-pasted into the output
Tokens(tt::TokenTreesView<'a, Span>),
Tokens {
tree: tt::TokenTreesView<'a, Span>,
origin: TokensOrigin,
},
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

The documentation comment for the Tokens variant should be updated to explain the new origin field. The current comment "token fragments are just copy-pasted into the output" is incomplete. Consider updating it to:

/// Token fragments are transcribed into the output. The `origin` field tracks whether
/// these tokens come from raw input (ident/tt/lifetime/literal metavars) or parsed AST
/// (ty/pat/stmt/block/etc metavars). AST-derived fragments preserve their structure
/// during transcription by not stripping invisible delimiters.

This provides context for the new field and explains why it matters.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Macro error: expected Expr

2 participants