-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Add manual_as_slice
lint
#14809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add manual_as_slice
lint
#14809
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a good starting point. I'd want some more test cases, and there is some duplication we can remove, but otherwise this seems mostly merge-worthy. I'd like to rename the lint though, it's too wordy. How about manual_as_slice
? That fits very well into our naming structure. Also please squash your commits when ready.
I like |
1a8a066
to
dc4e07b
Compare
I think you need to re-bless the tests. |
as_slice_instead_of_reference_full_range
lintmanual_as_slice
lint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should at least check that:
- the resulting type is a slice
- the
.as_slice()
/.as_mut_slice()
methods exist on the original type
or restrict the original type to those coming from core
/alloc
.
Otherwise, you take the risk of having a type implement [..]
for something else (let's say, in a domain-specific-language) without having .as_slice()
available. Here is an example:
#![feature(new_range_api)]
use std::ops::Index;
use std::range::RangeBounds;
struct Count;
impl<R: RangeBounds<()>> Index<R> for Count {
type Output = ();
fn index(&self, _: R) -> &Self::Output {
&()
}
}
fn main() {
_ = &Count[..];
}
It will suggest to use Count.as_slice()
even though this method does not exist on Count
.
I'm gonna restrict is to Vec, array and slice in that case, since doing this on a string also would not work |
Is it possible to get this working on vec since its not a language item? |
Language items are items that the compiler needs when it transforms code. For example, it needs However, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like the message to be shorter. Otherwise this looks mostly good. We may want to select a different lint group though. I'll start the final comment period soon.
545c550
to
a8a448d
Compare
This comment has been minimized.
This comment has been minimized.
☔ The latest upstream changes (possibly b379d54) made this pull request unmergeable. Please resolve the merge conflicts. |
macro_rules! perform_the_slice { | ||
($a:expr) => { | ||
&$a[..] | ||
//~^ manual_as_slice | ||
}; | ||
} | ||
|
||
perform_the_slice!([1, 2, 3]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we shouldn't lint inside macro definitions, because they may be called with arguments of different types, e.g. the following would be valid:
macro_rules! perform_the_slice {
($a:expr) => {
&$a[..]
//~^ manual_as_slice
};
}
perform_the_slice!([1, 2, 3]);
perform_the_slice!(String::new());
and putting the .as_slice()
would break the second call
let sugg_tail = match mutability { | ||
Mutability::Not => ".as_slice()", | ||
Mutability::Mut => ".as_mut_slice()", | ||
}; | ||
|
||
let borrow_span = expr.span.until(borrow.span); | ||
let app = Applicability::MachineApplicable; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: you could construct all of these inside the |diag| { .. }
closure below. That's probably marginally faster, but, more importantly, clearer, as otherwise one could think they're going to be used in some lint logic
I think it would work, you'd just need to suggest |
This pr adds the
manual_as_slice
lint.closes: #7633
changelog: add [
manual_as_slice
] lint