spade_typeinference/
traits.rs1use crate::{
2 equation::{TemplateTypeVarID, TypeVarID},
3 TypeState,
4};
5use itertools::Itertools;
6use serde::{Deserialize, Serialize};
7use spade_common::location_info::Loc;
8use spade_hir::{ImplBlock, ImplTarget, TraitName};
9use std::collections::{BTreeSet, HashMap};
10
11#[derive(Clone, Serialize, Deserialize)]
12pub struct TraitImpl {
13 pub name: TraitName,
14 pub target_type_params: Vec<TemplateTypeVarID>,
15 pub trait_type_params: Vec<TemplateTypeVarID>,
16 pub impl_block: ImplBlock,
17}
18
19#[derive(Clone, Serialize, Deserialize)]
20pub struct TraitImplList {
21 pub inner: HashMap<ImplTarget, Vec<TraitImpl>>,
22}
23
24impl TraitImplList {
25 pub fn new() -> Self {
26 Self {
27 inner: HashMap::new(),
28 }
29 }
30}
31
32#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
33pub struct TraitReq {
34 pub name: TraitName,
35 pub type_params: Vec<TypeVarID>,
36}
37
38impl TraitReq {
39 pub fn display(&self, type_state: &TypeState) -> String {
40 self.display_with_meta(false, type_state)
41 }
42
43 pub fn display_with_meta(&self, display_meta: bool, type_state: &TypeState) -> String {
44 if self.type_params.is_empty() {
45 format!("{}", self.name)
46 } else {
47 format!(
48 "{}<{}>",
49 self.name,
50 self.type_params
51 .iter()
52 .map(|t| format!("{}", t.display_with_meta(display_meta, type_state)))
53 .join(", ")
54 )
55 }
56 }
57
58 pub fn debug_display(&self, type_state: &TypeState) -> String {
59 if self.type_params.is_empty() {
60 format!("{}", self.name)
61 } else {
62 format!(
63 "{}<{}>",
64 self.name,
65 self.type_params
66 .iter()
67 .map(|t| format!("{}", t.debug_resolve(type_state).0))
68 .join(", ")
69 )
70 }
71 }
72}
73
74impl std::fmt::Debug for TraitReq {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 if self.type_params.is_empty() {
77 write!(f, "{}", self.name)
78 } else {
79 write!(
80 f,
81 "{}<{}>",
82 self.name,
83 self.type_params.iter().map(|t| format!("{t:?}")).join(", ")
84 )
85 }
86 }
87}
88
89#[derive(Clone, Debug, Serialize, Deserialize)]
90pub struct TraitList {
91 pub inner: Vec<Loc<TraitReq>>,
92}
93
94impl TraitList {
95 pub fn empty() -> Self {
96 Self { inner: vec![] }
97 }
98
99 pub fn from_vec(inner: Vec<Loc<TraitReq>>) -> Self {
100 Self { inner }
101 }
102
103 pub fn get_trait(&self, name: &TraitName) -> Option<&Loc<TraitReq>> {
104 self.inner.iter().find(|t| &t.name == name)
105 }
106
107 pub fn extend(self, other: Self) -> Self {
108 let merged = self
109 .inner
110 .into_iter()
111 .chain(other.inner.into_iter())
112 .collect::<BTreeSet<_>>()
113 .into_iter()
114 .collect_vec();
115
116 TraitList { inner: merged }
117 }
118
119 pub fn display_with_meta(&self, display_meta: bool, type_state: &TypeState) -> String {
120 self.inner
121 .iter()
122 .map(|t| t.inner.display_with_meta(display_meta, type_state))
123 .join(" + ")
124 }
125}
126
127impl PartialEq for TraitList {
130 fn eq(&self, _other: &Self) -> bool {
131 true
132 }
133}
134impl Eq for TraitList {}
135impl std::hash::Hash for TraitList {
136 fn hash<H: std::hash::Hasher>(&self, _state: &mut H) {}
137}
138impl PartialOrd for TraitList {
139 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
140 Some(self.cmp(other))
141 }
142}
143impl Ord for TraitList {
144 fn cmp(&self, _other: &Self) -> std::cmp::Ordering {
145 std::cmp::Ordering::Equal
146 }
147}