mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-27 07:00:55 +00:00
Auto merge of #11804 - y21:issue-11803, r=dswij
[`impl_trait_in_params`]: avoid ICE when function with `impl Trait` type has no parameters Fixes #11803 If I'm reading the old code correctly, it was taking the span of the first parameter (without checking that it exists, which caused the ICE) and uses that to figure out where the generic parameter to insert should go (cc `@blyxyas` you wrote the lint, is that correct?). This seemed equivalent to just `generics.span`, which doesn't require calculating the spans like that and simplifies it a fair bit changelog: don't ICE when function has no parameters but generics have an `impl Trait` type
This commit is contained in:
commit
783b914fae
3 changed files with 41 additions and 20 deletions
|
@ -5,18 +5,10 @@ use rustc_hir as hir;
|
|||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{Body, GenericParam, Generics, HirId, ImplItem, ImplItemKind, TraitItem, TraitItemKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{BytePos, Span};
|
||||
|
||||
use super::IMPL_TRAIT_IN_PARAMS;
|
||||
|
||||
fn report(
|
||||
cx: &LateContext<'_>,
|
||||
param: &GenericParam<'_>,
|
||||
ident: &Ident,
|
||||
generics: &Generics<'_>,
|
||||
first_param_span: Span,
|
||||
) {
|
||||
fn report(cx: &LateContext<'_>, param: &GenericParam<'_>, generics: &Generics<'_>) {
|
||||
// No generics with nested generics, and no generics like FnMut(x)
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
@ -35,12 +27,7 @@ fn report(
|
|||
);
|
||||
} else {
|
||||
diag.span_suggestion_with_style(
|
||||
Span::new(
|
||||
first_param_span.lo() - rustc_span::BytePos(1),
|
||||
ident.span.hi(),
|
||||
ident.span.ctxt(),
|
||||
ident.span.parent(),
|
||||
),
|
||||
generics.span,
|
||||
"add a type parameter",
|
||||
format!("<{{ /* Generic name */ }}: {}>", ¶m.name.ident().as_str()[5..]),
|
||||
rustc_errors::Applicability::HasPlaceholders,
|
||||
|
@ -52,13 +39,13 @@ fn report(
|
|||
}
|
||||
|
||||
pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body: &'tcx Body<'_>, hir_id: HirId) {
|
||||
if let FnKind::ItemFn(ident, generics, _) = kind
|
||||
if let FnKind::ItemFn(_, generics, _) = kind
|
||||
&& cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public()
|
||||
&& !is_in_test_function(cx.tcx, hir_id)
|
||||
{
|
||||
for param in generics.params {
|
||||
if param.is_impl_trait() {
|
||||
report(cx, param, ident, generics, body.params[0].span);
|
||||
report(cx, param, generics);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +63,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
|
|||
{
|
||||
for param in impl_item.generics.params {
|
||||
if param.is_impl_trait() {
|
||||
report(cx, param, &impl_item.ident, impl_item.generics, body.params[0].span);
|
||||
report(cx, param, impl_item.generics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,8 +79,7 @@ pub(super) fn check_trait_item(cx: &LateContext<'_>, trait_item: &TraitItem<'_>,
|
|||
{
|
||||
for param in trait_item.generics.params {
|
||||
if param.is_impl_trait() {
|
||||
let sp = trait_item.ident.span.with_hi(trait_item.ident.span.hi() + BytePos(1));
|
||||
report(cx, param, &trait_item.ident, trait_item.generics, sp.shrink_to_hi());
|
||||
report(cx, param, trait_item.generics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
9
tests/ui/crashes/ice-11803.rs
Normal file
9
tests/ui/crashes/ice-11803.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
//@no-rustfix
|
||||
|
||||
#![warn(clippy::impl_trait_in_params)]
|
||||
|
||||
pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>>() {
|
||||
extern "C" fn implementation_detail() {}
|
||||
}
|
||||
|
||||
fn main() {}
|
26
tests/ui/crashes/ice-11803.stderr
Normal file
26
tests/ui/crashes/ice-11803.stderr
Normal file
|
@ -0,0 +1,26 @@
|
|||
error: `impl Trait` used as a function parameter
|
||||
--> $DIR/ice-11803.rs:5:54
|
||||
|
|
||||
LL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>>() {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::impl-trait-in-params` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::impl_trait_in_params)]`
|
||||
help: add a type parameter
|
||||
|
|
||||
LL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>, { /* Generic name */ }: Clone>() {
|
||||
| +++++++++++++++++++++++++++++++
|
||||
|
||||
error: `impl Trait` used as a function parameter
|
||||
--> $DIR/ice-11803.rs:5:33
|
||||
|
|
||||
LL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>>() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: add a type parameter
|
||||
|
|
||||
LL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>, { /* Generic name */ }: Iterator<Item = impl Clone>>() {
|
||||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in a new issue