Skip to content

Commit 42eba1b

Browse files
committed
Reorder functions
1 parent eb7079c commit 42eba1b

File tree

1 file changed

+137
-137
lines changed

1 file changed

+137
-137
lines changed

clippy_lints/src/lifetimes.rs

Lines changed: 137 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -202,143 +202,6 @@ fn check_fn_inner<'tcx>(
202202
}
203203
}
204204

205-
/// Generate diagnostic messages for elidable lifetimes.
206-
fn report_elidable_lifetimes(
207-
cx: &LateContext<'_>,
208-
generics: &Generics<'_>,
209-
elidable_lts: &[LocalDefId],
210-
usages: &[Lifetime],
211-
include_suggestions: bool,
212-
) {
213-
let lts = elidable_lts
214-
.iter()
215-
// In principle, the result of the call to `Node::ident` could be `unwrap`ped, as `DefId` should refer to a
216-
// `Node::GenericParam`.
217-
.filter_map(|&def_id| cx.tcx.hir_node_by_def_id(def_id).ident())
218-
.map(|ident| ident.to_string())
219-
.collect::<Vec<_>>()
220-
.join(", ");
221-
222-
span_lint_and_then(
223-
cx,
224-
NEEDLESS_LIFETIMES,
225-
elidable_lts
226-
.iter()
227-
.map(|&lt| cx.tcx.def_span(lt))
228-
.chain(usages.iter().filter_map(|usage| {
229-
if let LifetimeName::Param(def_id) = usage.res
230-
&& elidable_lts.contains(&def_id)
231-
{
232-
return Some(usage.ident.span);
233-
}
234-
235-
None
236-
}))
237-
.collect_vec(),
238-
format!("the following explicit lifetimes could be elided: {lts}"),
239-
|diag| {
240-
if !include_suggestions {
241-
return;
242-
};
243-
244-
if let Some(suggestions) = elision_suggestions(cx, generics, elidable_lts, usages) {
245-
diag.multipart_suggestion("elide the lifetimes", suggestions, Applicability::MachineApplicable);
246-
}
247-
},
248-
);
249-
}
250-
251-
fn elision_suggestions(
252-
cx: &LateContext<'_>,
253-
generics: &Generics<'_>,
254-
elidable_lts: &[LocalDefId],
255-
usages: &[Lifetime],
256-
) -> Option<Vec<(Span, String)>> {
257-
let explicit_params = generics
258-
.params
259-
.iter()
260-
.filter(|param| !param.is_elided_lifetime() && !param.is_impl_trait())
261-
.collect::<Vec<_>>();
262-
263-
let mut suggestions = if elidable_lts.len() == explicit_params.len() {
264-
// if all the params are elided remove the whole generic block
265-
//
266-
// fn x<'a>() {}
267-
// ^^^^
268-
vec![(generics.span, String::new())]
269-
} else {
270-
elidable_lts
271-
.iter()
272-
.map(|&id| {
273-
let pos = explicit_params.iter().position(|param| param.def_id == id)?;
274-
let param = explicit_params.get(pos)?;
275-
276-
let span = if let Some(next) = explicit_params.get(pos + 1) {
277-
// fn x<'prev, 'a, 'next>() {}
278-
// ^^^^
279-
param.span.until(next.span)
280-
} else {
281-
// `pos` should be at least 1 here, because the param in position 0 would either have a `next`
282-
// param or would have taken the `elidable_lts.len() == explicit_params.len()` branch.
283-
let prev = explicit_params.get(pos - 1)?;
284-
285-
// fn x<'prev, 'a>() {}
286-
// ^^^^
287-
param.span.with_lo(prev.span.hi())
288-
};
289-
290-
Some((span, String::new()))
291-
})
292-
.collect::<Option<Vec<_>>>()?
293-
};
294-
295-
suggestions.extend(
296-
usages
297-
.iter()
298-
.filter(|usage| named_lifetime(usage).map_or(false, |id| elidable_lts.contains(&id)))
299-
.map(|usage| {
300-
match cx.tcx.parent_hir_node(usage.hir_id) {
301-
Node::Ty(Ty {
302-
kind: TyKind::Ref(..), ..
303-
}) => {
304-
// expand `&'a T` to `&'a T`
305-
// ^^ ^^^
306-
let span = cx.sess().source_map().span_extend_while_whitespace(usage.ident.span);
307-
308-
(span, String::new())
309-
},
310-
// `T<'a>` and `impl Foo + 'a` should be replaced by `'_`
311-
_ => (usage.ident.span, String::from("'_")),
312-
}
313-
}),
314-
);
315-
316-
Some(suggestions)
317-
}
318-
319-
// elision doesn't work for explicit self types, see rust-lang/rust#69064
320-
fn explicit_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Ident>) -> bool {
321-
if let Some(ident) = ident
322-
&& ident.name == kw::SelfLower
323-
&& !func.implicit_self.has_implicit_self()
324-
&& let Some(self_ty) = func.inputs.first()
325-
{
326-
let mut visitor = RefVisitor::new(cx);
327-
visitor.visit_ty(self_ty);
328-
329-
!visitor.all_lts().is_empty()
330-
} else {
331-
false
332-
}
333-
}
334-
335-
fn named_lifetime(lt: &Lifetime) -> Option<LocalDefId> {
336-
match lt.res {
337-
LifetimeName::Param(id) if !lt.is_anonymous() => Some(id),
338-
_ => None,
339-
}
340-
}
341-
342205
fn could_use_elision<'tcx>(
343206
cx: &LateContext<'tcx>,
344207
func: &'tcx FnDecl<'_>,
@@ -461,6 +324,22 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxHashSet<LocalDefId
461324
.collect()
462325
}
463326

327+
// elision doesn't work for explicit self types, see rust-lang/rust#69064
328+
fn explicit_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Ident>) -> bool {
329+
if let Some(ident) = ident
330+
&& ident.name == kw::SelfLower
331+
&& !func.implicit_self.has_implicit_self()
332+
&& let Some(self_ty) = func.inputs.first()
333+
{
334+
let mut visitor = RefVisitor::new(cx);
335+
visitor.visit_ty(self_ty);
336+
337+
!visitor.all_lts().is_empty()
338+
} else {
339+
false
340+
}
341+
}
342+
464343
/// Number of times each named lifetime occurs in the given slice. Returns a vector to preserve
465344
/// relative order.
466345
#[must_use]
@@ -481,6 +360,13 @@ fn named_lifetime_occurrences(lts: &[Lifetime]) -> Vec<(LocalDefId, usize)> {
481360
occurrences
482361
}
483362

363+
fn named_lifetime(lt: &Lifetime) -> Option<LocalDefId> {
364+
match lt.res {
365+
LifetimeName::Param(id) if !lt.is_anonymous() => Some(id),
366+
_ => None,
367+
}
368+
}
369+
484370
struct RefVisitor<'a, 'tcx> {
485371
cx: &'a LateContext<'tcx>,
486372
lts: Vec<Lifetime>,
@@ -781,6 +667,120 @@ fn report_elidable_impl_lifetimes<'tcx>(
781667
report_elidable_lifetimes(cx, impl_.generics, &elidable_lts, &usages, true);
782668
}
783669

670+
/// Generate diagnostic messages for elidable lifetimes.
671+
fn report_elidable_lifetimes(
672+
cx: &LateContext<'_>,
673+
generics: &Generics<'_>,
674+
elidable_lts: &[LocalDefId],
675+
usages: &[Lifetime],
676+
include_suggestions: bool,
677+
) {
678+
let lts = elidable_lts
679+
.iter()
680+
// In principle, the result of the call to `Node::ident` could be `unwrap`ped, as `DefId` should refer to a
681+
// `Node::GenericParam`.
682+
.filter_map(|&def_id| cx.tcx.hir_node_by_def_id(def_id).ident())
683+
.map(|ident| ident.to_string())
684+
.collect::<Vec<_>>()
685+
.join(", ");
686+
687+
span_lint_and_then(
688+
cx,
689+
NEEDLESS_LIFETIMES,
690+
elidable_lts
691+
.iter()
692+
.map(|&lt| cx.tcx.def_span(lt))
693+
.chain(usages.iter().filter_map(|usage| {
694+
if let LifetimeName::Param(def_id) = usage.res
695+
&& elidable_lts.contains(&def_id)
696+
{
697+
return Some(usage.ident.span);
698+
}
699+
700+
None
701+
}))
702+
.collect_vec(),
703+
format!("the following explicit lifetimes could be elided: {lts}"),
704+
|diag| {
705+
if !include_suggestions {
706+
return;
707+
};
708+
709+
if let Some(suggestions) = elision_suggestions(cx, generics, elidable_lts, usages) {
710+
diag.multipart_suggestion("elide the lifetimes", suggestions, Applicability::MachineApplicable);
711+
}
712+
},
713+
);
714+
}
715+
716+
fn elision_suggestions(
717+
cx: &LateContext<'_>,
718+
generics: &Generics<'_>,
719+
elidable_lts: &[LocalDefId],
720+
usages: &[Lifetime],
721+
) -> Option<Vec<(Span, String)>> {
722+
let explicit_params = generics
723+
.params
724+
.iter()
725+
.filter(|param| !param.is_elided_lifetime() && !param.is_impl_trait())
726+
.collect::<Vec<_>>();
727+
728+
let mut suggestions = if elidable_lts.len() == explicit_params.len() {
729+
// if all the params are elided remove the whole generic block
730+
//
731+
// fn x<'a>() {}
732+
// ^^^^
733+
vec![(generics.span, String::new())]
734+
} else {
735+
elidable_lts
736+
.iter()
737+
.map(|&id| {
738+
let pos = explicit_params.iter().position(|param| param.def_id == id)?;
739+
let param = explicit_params.get(pos)?;
740+
741+
let span = if let Some(next) = explicit_params.get(pos + 1) {
742+
// fn x<'prev, 'a, 'next>() {}
743+
// ^^^^
744+
param.span.until(next.span)
745+
} else {
746+
// `pos` should be at least 1 here, because the param in position 0 would either have a `next`
747+
// param or would have taken the `elidable_lts.len() == explicit_params.len()` branch.
748+
let prev = explicit_params.get(pos - 1)?;
749+
750+
// fn x<'prev, 'a>() {}
751+
// ^^^^
752+
param.span.with_lo(prev.span.hi())
753+
};
754+
755+
Some((span, String::new()))
756+
})
757+
.collect::<Option<Vec<_>>>()?
758+
};
759+
760+
suggestions.extend(
761+
usages
762+
.iter()
763+
.filter(|usage| named_lifetime(usage).map_or(false, |id| elidable_lts.contains(&id)))
764+
.map(|usage| {
765+
match cx.tcx.parent_hir_node(usage.hir_id) {
766+
Node::Ty(Ty {
767+
kind: TyKind::Ref(..), ..
768+
}) => {
769+
// expand `&'a T` to `&'a T`
770+
// ^^ ^^^
771+
let span = cx.sess().source_map().span_extend_while_whitespace(usage.ident.span);
772+
773+
(span, String::new())
774+
},
775+
// `T<'a>` and `impl Foo + 'a` should be replaced by `'_`
776+
_ => (usage.ident.span, String::from("'_")),
777+
}
778+
}),
779+
);
780+
781+
Some(suggestions)
782+
}
783+
784784
struct BodyLifetimeChecker;
785785

786786
impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker {

0 commit comments

Comments
 (0)