Skip to content

Commit 6a58a19

Browse files
committed
inline function
1 parent fddd397 commit 6a58a19

File tree

1 file changed

+63
-70
lines changed

1 file changed

+63
-70
lines changed

clippy_lints/src/iter_without_into_iter.rs

Lines changed: 63 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use clippy_utils::get_parent_as_impl;
33
use clippy_utils::source::snippet;
44
use clippy_utils::ty::{implements_trait, make_normalized_projection};
55
use rustc_errors::Applicability;
6-
use rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, Mutability, TyKind};
6+
use rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, TyKind};
77
use rustc_lint::{LateContext, LateLintPass};
88
use rustc_session::{declare_lint_pass, declare_tool_lint};
99
use rustc_span::sym;
@@ -56,58 +56,60 @@ fn is_nameable_in_impl_trait(ty: &rustc_hir::Ty<'_>) -> bool {
5656
!matches!(ty.kind, TyKind::OpaqueDef(..))
5757
}
5858

59-
fn check_for_mutability(cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>, expected_mtbl: Mutability) {
60-
let item_did = item.owner_id.to_def_id();
61-
let (borrow_prefix, name, expected_implicit_self) = match expected_mtbl {
62-
Mutability::Not => ("&", "iter", ImplicitSelfKind::ImmRef),
63-
Mutability::Mut => ("&mut ", "iter_mut", ImplicitSelfKind::MutRef),
64-
};
59+
impl LateLintPass<'_> for IterWithoutIntoIter {
60+
fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) {
61+
let item_did = item.owner_id.to_def_id();
62+
let (borrow_prefix, expected_implicit_self) = match item.ident.name {
63+
sym::iter => ("&", ImplicitSelfKind::ImmRef),
64+
sym::iter_mut => ("&mut ", ImplicitSelfKind::MutRef),
65+
_ => return,
66+
};
6567

66-
if let ImplItemKind::Fn(sig, _) = item.kind
67-
&& let FnRetTy::Return(ret) = sig.decl.output
68-
&& is_nameable_in_impl_trait(ret)
69-
&& cx.tcx.generics_of(item_did).params.is_empty()
70-
&& sig.decl.implicit_self == expected_implicit_self
71-
&& sig.decl.inputs.len() == 1
72-
&& let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id())
73-
&& imp.of_trait.is_none()
74-
&& let sig = cx.tcx.liberate_late_bound_regions(
75-
item_did,
76-
cx.tcx.fn_sig(item_did).skip_binder()
77-
)
78-
&& let ref_ty = sig.inputs()[0]
79-
&& let Some(into_iter_did) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
80-
&& let ret_ty = sig.output()
81-
// Order is important here, we need to check that the `fn iter` return type actually implements `IntoIterator`
82-
// *before* normalizing `<_ as IntoIterator>::Item` (otherwise make_normalized_projection ICEs)
83-
&& implements_trait(cx, ret_ty, into_iter_did, &[])
84-
&& let Some(iter_ty) = make_normalized_projection(
85-
cx.tcx,
86-
cx.param_env,
87-
into_iter_did,
88-
sym!(Item),
89-
[ret_ty],
90-
)
91-
// Only lint if the `IntoIterator` impl doesn't actually exist
92-
&& !implements_trait(cx, ref_ty, into_iter_did, &[])
93-
{
94-
let self_ty_snippet = format!("{borrow_prefix}{}", snippet(cx, imp.self_ty.span, ".."));
68+
if let ImplItemKind::Fn(sig, _) = item.kind
69+
&& let FnRetTy::Return(ret) = sig.decl.output
70+
&& is_nameable_in_impl_trait(ret)
71+
&& cx.tcx.generics_of(item_did).params.is_empty()
72+
&& sig.decl.implicit_self == expected_implicit_self
73+
&& sig.decl.inputs.len() == 1
74+
&& let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id())
75+
&& imp.of_trait.is_none()
76+
&& let sig = cx.tcx.liberate_late_bound_regions(
77+
item_did,
78+
cx.tcx.fn_sig(item_did).skip_binder()
79+
)
80+
&& let ref_ty = sig.inputs()[0]
81+
&& let Some(into_iter_did) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
82+
&& let ret_ty = sig.output()
83+
// Order is important here, we need to check that the `fn iter` return type actually implements `IntoIterator`
84+
// *before* normalizing `<_ as IntoIterator>::Item` (otherwise make_normalized_projection ICEs)
85+
&& implements_trait(cx, ret_ty, into_iter_did, &[])
86+
&& let Some(iter_ty) = make_normalized_projection(
87+
cx.tcx,
88+
cx.param_env,
89+
into_iter_did,
90+
sym!(Item),
91+
[ret_ty],
92+
)
93+
// Only lint if the `IntoIterator` impl doesn't actually exist
94+
&& !implements_trait(cx, ref_ty, into_iter_did, &[])
95+
{
96+
let self_ty_snippet = format!("{borrow_prefix}{}", snippet(cx, imp.self_ty.span, ".."));
9597

96-
span_lint_and_then(
97-
cx,
98-
ITER_WITHOUT_INTO_ITER,
99-
item.span,
100-
&format!("`{name}` method without an `IntoIterator` impl for `{self_ty_snippet}`"),
101-
|diag| {
102-
// Get the lower span of the `impl` block, and insert the suggestion right before it:
103-
// impl X {
104-
// ^ fn iter(&self) -> impl IntoIterator { ... }
105-
// }
106-
let span_behind_impl = cx.tcx
107-
.def_span(cx.tcx.hir().parent_id(item.hir_id()).owner.def_id)
108-
.shrink_to_lo();
98+
span_lint_and_then(
99+
cx,
100+
ITER_WITHOUT_INTO_ITER,
101+
item.span,
102+
&format!("`{}` method without an `IntoIterator` impl for `{self_ty_snippet}`", item.ident),
103+
|diag| {
104+
// Get the lower span of the `impl` block, and insert the suggestion right before it:
105+
// impl X {
106+
// ^ fn iter(&self) -> impl IntoIterator { ... }
107+
// }
108+
let span_behind_impl = cx.tcx
109+
.def_span(cx.tcx.hir().parent_id(item.hir_id()).owner.def_id)
110+
.shrink_to_lo();
109111

110-
let sugg = format!(
112+
let sugg = format!(
111113
"
112114
impl IntoIterator for {self_ty_snippet} {{
113115
type IntoIter = {ret_ty};
@@ -117,25 +119,16 @@ impl IntoIterator for {self_ty_snippet} {{
117119
}}
118120
}}
119121
"
120-
);
121-
diag.span_suggestion_verbose(
122-
span_behind_impl,
123-
format!("consider implementing `IntoIterator` for `{self_ty_snippet}`"),
124-
sugg,
125-
// Suggestion is on a best effort basis, might need some adjustments by the user
126-
// such as adding some lifetimes in the associated types, or importing types.
127-
Applicability::Unspecified,
128-
);
129-
});
130-
}
131-
}
132-
133-
impl LateLintPass<'_> for IterWithoutIntoIter {
134-
fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) {
135-
match item.ident.name {
136-
sym::iter => check_for_mutability(cx, item, Mutability::Not),
137-
sym::iter_mut => check_for_mutability(cx, item, Mutability::Mut),
138-
_ => {},
139-
};
122+
);
123+
diag.span_suggestion_verbose(
124+
span_behind_impl,
125+
format!("consider implementing `IntoIterator` for `{self_ty_snippet}`"),
126+
sugg,
127+
// Suggestion is on a best effort basis, might need some adjustments by the user
128+
// such as adding some lifetimes in the associated types, or importing types.
129+
Applicability::Unspecified,
130+
);
131+
});
132+
}
140133
}
141134
}

0 commit comments

Comments
 (0)