about summary refs log tree commit diff
path: root/clippy_utils/src
diff options
context:
space:
mode:
authorJason Newcomb <jsnewcomb@pm.me>2022-04-05 21:14:42 -0400
committerJason Newcomb <jsnewcomb@pm.me>2022-06-27 13:14:25 -0400
commit2315f76f9d66b39db975bc722046cca55bc17079 (patch)
treef12789e0bee1631af4035465d19c136808cc31f9 /clippy_utils/src
parenteaa03ea911662b282d3c7bc7c3a29f9fb370b933 (diff)
downloadrust-2315f76f9d66b39db975bc722046cca55bc17079.tar.gz
rust-2315f76f9d66b39db975bc722046cca55bc17079.zip
Actually check lifetimes in `trivially_copy_pass_by_ref`
Diffstat (limited to 'clippy_utils/src')
-rw-r--r--clippy_utils/src/ty.rs32
1 files changed, 30 insertions, 2 deletions
diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs
index 227e97d37ec..4c079151f24 100644
--- a/clippy_utils/src/ty.rs
+++ b/clippy_utils/src/ty.rs
@@ -2,6 +2,7 @@
 
 #![allow(clippy::module_name_repetitions)]
 
+use core::ops::ControlFlow;
 use rustc_ast::ast::Mutability;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
@@ -13,8 +14,8 @@ use rustc_lint::LateContext;
 use rustc_middle::mir::interpret::{ConstValue, Scalar};
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
 use rustc_middle::ty::{
-    self, AdtDef, Binder, FnSig, IntTy, ParamEnv, Predicate, PredicateKind, Ty, TyCtxt, TypeFoldable, UintTy,
-    VariantDiscr,
+    self, AdtDef, Binder, BoundRegion, FnSig, IntTy, ParamEnv, Predicate, PredicateKind, Region, RegionKind, Ty,
+    TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor, UintTy, VariantDiscr,
 };
 use rustc_span::symbol::Ident;
 use rustc_span::{sym, Span, Symbol, DUMMY_SP};
@@ -667,3 +668,30 @@ pub fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
         false
     }
 }
+
+pub fn for_each_top_level_late_bound_region<B>(
+    ty: Ty<'_>,
+    f: impl FnMut(BoundRegion) -> ControlFlow<B>,
+) -> ControlFlow<B> {
+    struct V<F> {
+        index: u32,
+        f: F,
+    }
+    impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow<B>> TypeVisitor<'tcx> for V<F> {
+        type BreakTy = B;
+        fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow<Self::BreakTy> {
+            if let RegionKind::ReLateBound(idx, bound) = r.kind() && idx.as_u32() == self.index {
+                (self.f)(bound)
+            } else {
+                ControlFlow::Continue(())
+            }
+        }
+        fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow<Self::BreakTy> {
+            self.index += 1;
+            let res = t.super_visit_with(self);
+            self.index -= 1;
+            res
+        }
+    }
+    ty.visit_with(&mut V { index: 0, f })
+}