Skip to content

Don't mark replace_box suggestion machine-applicable for Box<&mut _> - #17554

Open
DoTuanAnh2k1 wants to merge 1 commit into
rust-lang:masterfrom
DoTuanAnh2k1:replace-box-mut-ref
Open

Don't mark replace_box suggestion machine-applicable for Box<&mut _>#17554
DoTuanAnh2k1 wants to merge 1 commit into
rust-lang:masterfrom
DoTuanAnh2k1:replace-box-mut-ref

Conversation

@DoTuanAnh2k1

@DoTuanAnh2k1 DoTuanAnh2k1 commented Aug 12, 2026

Copy link
Copy Markdown

replace_box flags b = Box::new(x) on an existing Box<T> and suggests writing to the boxed storage instead (*b = x) to skip an allocation. That suggestion is MachineApplicable, but for Box<&mut T> the two forms aren't interchangeable: *b = &mut x keeps the reference already stored in the box borrowed across the assignment, while b = Box::new(&mut x) drops the old box (and its borrow) first. As shown in the issue, that can change borrow-check results, so cargo clippy --fix could turn compiling code into code that no longer builds.

Keep emitting the lint (the extra allocation is still real), but downgrade the "replace existing content with inner value instead" suggestion to MaybeIncorrect when the boxed element type is a &mut reference. Other element types are unaffected.

Testing: added a Box<&mut _> case to tests/ui/replace_box.rs; the replace_box UI test passes and cargo dev fmt --check is clean. Clippy's UI harness applies suggestions regardless of applicability, so the downgrade isn't visible in the .fixed output — I confirmed it via the diagnostic's applicability field: the Box<&mut _> suggestion is now MaybeIncorrect, while Box<u32> stays MachineApplicable.

fixes #17549

changelog: [replace_box]: don't emit a machine-applicable suggestion for Box<&mut _>


Prepared with AI assistance; reviewed and tested by me.

@rustbot rustbot added S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Aug 12, 2026
@rustbot

rustbot commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome!

You should hear from one of our reviewers after this PR gets at least 2 reviews from the community.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@Gri-ffin Gri-ffin 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.

You can move this test case into its own replace_box_unfixable.rs file with //@no-rustfix

View changes since this review

Comment thread clippy_lints/src/replace_box.rs Outdated
// `*b = &mut x` keeps the box's existing borrow alive across the assignment,
// while `b = Box::new(&mut x)` drops the old box first; for `Box<&mut _>` that
// difference can change borrow-check results, so don't auto-apply the rewrite.
let mut app = if matches!(inner_ty.kind(), ty::Ref(_, _, Mutability::Mut)) {

@Jarcho Jarcho Aug 12, 2026

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.

This applies to any type with a region variable, not just mutable references. You can check inner_ty.flags().contains(HAS_RE_ERASED).

View changes since the review

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good call — switched to inner_ty.has_type_flags(TypeFlags::HAS_RE_ERASED) so it covers any boxed type carrying a lifetime, not just &mut. Checked &mut _, &_, and a struct with a lifetime param all come out MaybeIncorrect now, while plain values stay MachineApplicable.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Aug 12, 2026
@rustbot

rustbot commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

…nces

Rewriting `b = Box::new(x)` to `*b = x` keeps any borrow already stored in
the box alive across the assignment, whereas reassigning the box drops the
old one first. When the boxed type carries a lifetime that difference can
change borrow-check results, so the suggestion can't be applied blindly.
Keep emitting the lint but downgrade the suggestion to MaybeIncorrect when
the boxed type contains a region; other element types stay unchanged.
@DoTuanAnh2k1

Copy link
Copy Markdown
Author

Moved the cases into replace_box_unfixable.rs with //@no-rustfix, thanks. Also generalized the applicability check per Jarcho's review.

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Aug 20, 2026

@CommanderStorm CommanderStorm 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.

Community review: lgtm

View changes since this review

@rustbot

rustbot commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (possibly #17607) made this pull request unmergeable. Please resolve the merge conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned. 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.

clippy::replace_box suggests a MachineApplicable fix that is semantically questionable for Box<&mut T>

5 participants