Skip to content

fix(source-edit): place MoveSymbol imports at syntax boundaries - #4531

Open
ScriptedAlchemy wants to merge 1 commit into
fix/search-eval-canonical-corpusfrom
fix/move-import-syntax-boundaries
Open

ScriptedAlchemy wants to merge 1 commit into
fix/search-eval-canonical-corpusfrom
fix/move-import-syntax-boundaries

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

Merge #4478 first, followed by #4526, #4510, #4524, #4489, #4485, #4527, #4528, #4530, #4531, #4529, #4534, and #4541.

This PR is number 10 of 13, based on #4530. Merge #4529 next.

Use merge commits. After merging a parent PR, change its child's base to master before merging the child. Auto-merge is disabled.

Fixes #4420. Stack parent: #4530. Merge after the existing ordered stack using a merge commit.

Problem

insert_imports advanced one physical line per use and treated inner and outer attributes alike. A destination with a multi-line use std::{ ... }; got the new import spliced inside the group, and a destination starting with #![allow(dead_code)] got the import ahead of the inner attribute. Both produce invalid Rust.

Root cause

Insertion position came from a per-line prefix classifier (classify_leading_line), not from the Rust parse the dependency analyzer already uses.

Fix

  • The insertion byte boundary uses the existing canonical Rust parser: after module inner attributes, inner docs, leading comments and existing use/extern crate declarations, never inside one. Outer docs and attributes stay attached to the item they annotate.
  • A destination that has syntax errors (or no grammar) refuses the move with a typed error instead of guessing. Empty and missing destinations behave as before.
  • The line classifier and LeadingKind are deleted; the only remaining caller (inner-doc skip) uses is_inner_doc_line.

Verification

Red first (commit 1): move_symbol_inserts_imports_after_a_multiline_use_group, ..._after_module_inner_attributes and move_symbol_refuses_a_destination_that_does_not_parse failed (the first two with rustc errors on the generated destination). With the fix, bazel test //crates/tracedecay-source-edit:unit_test passes (all tests) and bazel build --config=clippy //crates/tracedecay-source-edit/... is clean.

🤖 Generated with Claude Code

Independent boundary regression and correction

An existing import and an outer attribute may share a physical line. Rounding the import's syntax end to the next line detached #[cfg(any())] from the following item and applied it to the newly inserted import. The real MoveSymbol fixture then failed Rust compilation because the moved function's Widget import was disabled.

The insertion uses the parsed node's byte boundary, preserves the destination text around it, and inserts a newline where necessary. The new regression executes the existing preview/publication journey and compiles the resulting fixture.

  • BEFORE: 0 passed / 1 failed; invocation 6fe80e3b-a163-429d-b651-e981eddd13c0, missing Widget after the move.
  • AFTER exact: 1 passed / 114 filtered; invocation eca65863-6a1e-4bff-9e79-7cb0d30b880d; affected formatting passed.
  • Full source-edit unit suite: 115 passed / 0 failed; invocation 7e338640-af8b-4361-926b-50d59a944904.

All runs used canonical Bazel targets with fresh test results. No timeout, budget, or host setting changed.

Scoped Clippy and final formatting passed in 8420704d-e70a-481c-b928-2d1a34aac5ef. The first Clippy run caught the now-unused splice_lines import; removing that import was the only change after the 115-test pass.

Stack integration

The parent stack already contains canonical byte-based destination rendering, typed source-edit-destination-syntax-unsupported refusal, validation for dependency-free Rust moves, and newline preservation. Integration retains that implementation rather than duplicating the parser. This layer keeps the real execution regressions and removes the obsolete line classifier in favor of the remaining inner-doc predicate. No destination validation or existing regression is dropped.

Integrated parent validation: 121 source-edit unit tests passed, with formatting, in c759f31b-2115-407e-aa85-1ffe9eb18855. This includes the parent destination tests and every new execution regression.

Integrated scoped Clippy passed in 2e8d67bd-73a9-4027-a613-d1ccadf75a10. Parent integration uses a merge commit and preserves the canonical renderer byte-for-byte.

@changeset-bot

changeset-bot Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 87ffb73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔍 Devin Review: 1 flag

Not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/search-eval-canonical-corpus branch from d5b13e2 to 46532d2 Compare October 25, 2026 10:35
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/move-import-syntax-boundaries branch from 05f3027 to 770114e Compare October 25, 2026 10:35
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/search-eval-canonical-corpus branch from 46532d2 to deb6c24 Compare October 25, 2026 11:27
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/move-import-syntax-boundaries branch from 770114e to 017328f Compare October 25, 2026 11:27
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/search-eval-canonical-corpus branch from deb6c24 to e6d05d4 Compare October 25, 2026 19:42
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/move-import-syntax-boundaries branch from 8b07ca6 to eea3ca0 Compare October 25, 2026 19:42
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/search-eval-canonical-corpus branch from e6d05d4 to e5d734b Compare October 25, 2026 20:06
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/move-import-syntax-boundaries branch from eea3ca0 to 443b1f9 Compare October 25, 2026 20:06
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/search-eval-canonical-corpus branch from 379a571 to e852784 Compare October 26, 2026 03:42
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/move-import-syntax-boundaries branch from e0f3699 to 5e25f96 Compare October 26, 2026 03:42
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/search-eval-canonical-corpus branch from e852784 to 3e31ec1 Compare October 26, 2026 03:51
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/move-import-syntax-boundaries branch from 5e25f96 to 29f5cbb Compare October 26, 2026 03:51
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/search-eval-canonical-corpus branch from 3e31ec1 to e4d884f Compare October 26, 2026 03:59
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/move-import-syntax-boundaries branch from 29f5cbb to d59e2e4 Compare October 26, 2026 03:59
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/search-eval-canonical-corpus branch from e4d884f to 12bc45d Compare October 26, 2026 05:15
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/move-import-syntax-boundaries branch from d59e2e4 to 9c978fb Compare October 26, 2026 05:15
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/search-eval-canonical-corpus branch from 12bc45d to 0ffccb3 Compare October 26, 2026 05:35
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/move-import-syntax-boundaries branch from 9c978fb to 68896c4 Compare October 26, 2026 05:35
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/search-eval-canonical-corpus branch from 0ffccb3 to 2e642cb Compare October 26, 2026 08:58
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/move-import-syntax-boundaries branch from 68896c4 to 87ffb73 Compare October 26, 2026 08:58
ScriptedAlchemy added a commit that referenced this pull request Oct 26, 2026

This branch has not been deployed

No deployments
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.

fix(source-edit): insert MoveSymbol imports at syntax boundaries, not inside grouped imports or before inner attributes

1 participant