about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCameron Steffen <cam.steffen94@gmail.com>2022-01-04 17:24:23 -0600
committerCameron Steffen <cam.steffen94@gmail.com>2022-01-28 15:45:41 -0600
commitbea09a2329676e48ea9f780c47e27d653417a4e3 (patch)
treeabfb3a075797fb96eb2afaa4924bd3514d07e3fa
parentcc975929c528d0883d7553c53dc47030c08d01e0 (diff)
downloadrust-bea09a2329676e48ea9f780c47e27d653417a4e3.tar.gz
rust-bea09a2329676e48ea9f780c47e27d653417a4e3.zip
Add path_def_id util
-rw-r--r--clippy_utils/src/lib.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 28bca902e19..8cc4f0449e3 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -497,6 +497,43 @@ pub fn path_to_local_id(expr: &Expr<'_>, id: HirId) -> bool {
     path_to_local(expr) == Some(id)
 }
 
+pub trait MaybePath<'hir> {
+    fn hir_id(&self) -> HirId;
+    fn qpath_opt(&self) -> Option<&QPath<'hir>>;
+}
+
+macro_rules! maybe_path {
+    ($ty:ident, $kind:ident) => {
+        impl<'hir> MaybePath<'hir> for hir::$ty<'hir> {
+            fn hir_id(&self) -> HirId {
+                self.hir_id
+            }
+            fn qpath_opt(&self) -> Option<&QPath<'hir>> {
+                match &self.kind {
+                    hir::$kind::Path(qpath) => Some(qpath),
+                    _ => None,
+                }
+            }
+        }
+    };
+}
+maybe_path!(Expr, ExprKind);
+maybe_path!(Pat, PatKind);
+maybe_path!(Ty, TyKind);
+
+/// If `maybe_path` is a path node, resolves it, otherwise returns `Res::Err`
+pub fn path_res<'tcx>(cx: &LateContext<'_>, maybe_path: &impl MaybePath<'tcx>) -> Res {
+    match maybe_path.qpath_opt() {
+        None => Res::Err,
+        Some(qpath) => cx.qpath_res(qpath, maybe_path.hir_id()),
+    }
+}
+
+/// If `maybe_path` is a path node which resolves to an item, retrieves the item ID
+pub fn path_def_id<'tcx>(cx: &LateContext<'_>, maybe_path: &impl MaybePath<'tcx>) -> Option<DefId> {
+    path_res(cx, maybe_path).opt_def_id()
+}
+
 /// Resolves a def path like `std::vec::Vec`.
 /// This function is expensive and should be used sparingly.
 pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {