rapx/analysis/core/api_dependency/graph/
transform.rs1use super::dep_edge::DepEdge;
2use super::{ApiDependencyGraph, DepNode, TyWrapper};
3use petgraph::graph::NodeIndex;
4use rustc_middle::ty::{self};
5use std::fmt::Display;
6
7static ALL_TRANSFORMKIND: [TransformKind; 2] = [
8 TransformKind::Ref(ty::Mutability::Not),
9 TransformKind::Ref(ty::Mutability::Mut),
10 ];
13
14#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)]
15pub enum TransformKind {
16 Ref(ty::Mutability),
17 Unwrap, }
19
20impl TransformKind {
21 pub fn all() -> &'static [TransformKind] {
22 &ALL_TRANSFORMKIND
23 }
24}
25
26impl Display for TransformKind {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 match self {
29 TransformKind::Ref(mutability) => write!(f, "{}T", mutability.ref_prefix_str()),
30 TransformKind::Unwrap => write!(f, "Unwrap"),
31 }
32 }
33}
34
35impl<'tcx> ApiDependencyGraph<'tcx> {
36 pub fn update_transform_edges(&mut self) {
37 for node_index in self.graph.node_indices() {
38 if let DepNode::Ty(ty) = self.graph[node_index] {
39 self.add_possible_transform::<3>(ty, 0);
40 }
41 }
42 }
43
44 fn add_possible_transform<const MAX_DEPTH: usize>(
45 &mut self,
46 current_ty: TyWrapper<'tcx>,
47 depth: usize,
48 ) -> Option<NodeIndex> {
49 if depth > 0 {
50 let index = self.get_index(DepNode::Ty(current_ty));
51 if index.is_some() {
52 return index;
53 }
54 }
55
56 if depth >= MAX_DEPTH {
57 return None;
58 }
59
60 let mut ret = None;
61 for kind in TransformKind::all() {
62 let new_ty = current_ty.transform(*kind, self.tcx()); if let Some(next_index) = self.add_possible_transform::<MAX_DEPTH>(new_ty, depth + 1) {
64 let current_index = self.get_or_create_index(DepNode::Ty(current_ty));
65 self.add_edge_once(current_index, next_index, DepEdge::transform(*kind));
66 ret = Some(current_index);
67 }
68 }
69 ret
70 }
71}