Skip to content

Conversation

@IoaNNUwU
Copy link
Contributor

@IoaNNUwU IoaNNUwU commented Oct 22, 2025

Fixes: #147944

fn main() {
    let mut vec = vec![1, 2, 3, 4, 5];
    vec.drain([..3]);
}

Using array of 1 range instead of range itself as argument of impl RangeBounds now additionally produces this suggestion:

help: consider removing `[]`
   |
LL -     vec.drain([..3]);
LL +     vec.drain(..3);
   |

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 22, 2025
@rustbot
Copy link
Collaborator

rustbot commented Oct 22, 2025

r? @madsmtm

rustbot has assigned @madsmtm.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Copy link
Contributor

@madsmtm madsmtm left a comment

Choose a reason for hiding this comment

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

This seems like a mistake that a new user could reasonably hit if they haven't internalized that item[..x] means Index[Mut] with Range parameter, and think that the ..x syntax must be wrapped in [].

So +1 on adding the diagnostic. Have a few comments on the implementation, see below.

View changes since this review

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 24, 2025
@rustbot
Copy link
Collaborator

rustbot commented Oct 25, 2025

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-log-analyzer

This comment has been minimized.

@IoaNNUwU
Copy link
Contributor Author

I used let pattern chain instead of early returns similarly how other functions in this file do this to make it even less verbose.

I edited the tests to include this example:

let range = [1..5];
let mut vec = vec![1, 2, 3, 4, 5];
vec.drain(range);

And I have a question about this. Should compiler give an error in this case or is it outside of a scope for such suggestion?

Right now suggest_remove_brackets_from_range only works for inline ranges - for that it checks if snippet starts and ends with [, ]. It this the right solution?

I also wonder if something like this should be a part of this PR:

let range_wrong: Range<usize> = [1..5];
//               ^^^^^^^^^^^^   ^^^^^^ array [Range<usize>; 1]
//               struct Range<usize>

@IoaNNUwU
Copy link
Contributor Author

@rustbot label -S-waiting-on-author +S-waiting-on-review

@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 (such as code changes or more information) from the author. labels Oct 26, 2025
Copy link
Contributor

@madsmtm madsmtm left a comment

Choose a reason for hiding this comment

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

Sorry for the delay.

I used let pattern chain instead of early returns similarly how other functions in this file do this to make it even less verbose.

Thanks, I like it so far!

I answered the rest of your questions in inline comments.

View changes since this review

Comment on lines +7 to +12
// Should not produce this suggestion:

let range = [1..5];
let mut vec = vec![1, 2, 3, 4, 5];
vec.drain(range);
//~^ ERROR: the trait bound `[std::ops::Range<{integer}>; 1]: RangeBounds<usize>` is not satisfied [E0277]
Copy link
Contributor

Choose a reason for hiding this comment

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

I edited the tests to include this example:

let range = [1..5];
let mut vec = vec![1, 2, 3, 4, 5];
vec.drain(range);

And I have a question about this. Should compiler give an error in this case or is it outside of a scope for such suggestion?

I think it's fine to leave this as future work, maybe with the note like this instead:

Suggested change
// Should not produce this suggestion:
let range = [1..5];
let mut vec = vec![1, 2, 3, 4, 5];
vec.drain(range);
//~^ ERROR: the trait bound `[std::ops::Range<{integer}>; 1]: RangeBounds<usize>` is not satisfied [E0277]
// Does not produce this suggestion (but could in the future):
let range = [1..5];
let mut vec = vec![1, 2, 3, 4, 5];
vec.drain(range);
//~^ ERROR: the trait bound `[std::ops::Range<{integer}>; 1]: RangeBounds<usize>` is not satisfied [E0277]
// Should not produce this suggestion:

@@ -0,0 +1,27 @@
fn main() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I also wonder if something like this should be a part of this PR:

let range_wrong: Range<usize> = [1..5];
//               ^^^^^^^^^^^^   ^^^^^^ array [Range<usize>; 1]
//               struct Range<usize>

I'm fine with it not being so, though maybe you could add it as a test as well?

Comment on lines +5197 to +5198
&& snip.starts_with('[')
&& snip.ends_with(']')
Copy link
Contributor

Choose a reason for hiding this comment

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

Right now suggest_remove_brackets_from_range only works for inline ranges - for that it checks if snippet starts and ends with [, ]. It this the right solution?

Well, it does make it considerably easier to construct the suggestion, and there is precedence for it in suggest_block_to_brackets, so I think it's fine.

Comment on lines +5192 to +5193
&& let ty::Adt(adt_def, _) = inner_type.kind()
&& self.tcx.is_range(adt_def.did())
Copy link
Contributor

Choose a reason for hiding this comment

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

I just realized, we already have something that describes whether a type is a valid range: the RangeBounds trait.

So maybe we can use something like this instead:

Suggested change
&& let ty::Adt(adt_def, _) = inner_type.kind()
&& self.tcx.is_range(adt_def.did())
// NOTE: Assumes that arrays do not implement `RangeBounds`.
&& let Some(range_bounds) = self.tcx.get_diagnostic_item(sym::RangeBounds)
&& self.type_implements_trait(range_bounds, [inner_type], param_env).must_apply_modulo_regions()

And then we can get rid of the is_range function?

vec.drain([..]);
//~^ ERROR: the trait bound `[RangeFull; 1]: RangeBounds<usize>` is not satisfied [E0277]
//~| SUGGESTION: ..
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a test that calls a different method than Vec::drain?

And possibly also a test like:

let my_range = 1..3;
vec.drain([my_range]);

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Suggest removing [] for array of 1 RangeBounds arguments.

4 participants