aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs81
1 files changed, 47 insertions, 34 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 884cea52a..31f726f35 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -78,7 +78,7 @@ pub enum Ty {
78 /// The definition of the function / constructor. 78 /// The definition of the function / constructor.
79 def: CallableDef, 79 def: CallableDef,
80 /// Parameters and return type 80 /// Parameters and return type
81 sig: Arc<FnSig>, 81 sig: FnSig,
82 /// Substitutions for the generic parameters of the type 82 /// Substitutions for the generic parameters of the type
83 substs: Substs, 83 substs: Substs,
84 }, 84 },
@@ -91,7 +91,7 @@ pub enum Ty {
91 /// fn foo() -> i32 { 1 } 91 /// fn foo() -> i32 { 1 }
92 /// let bar: fn() -> i32 = foo; 92 /// let bar: fn() -> i32 = foo;
93 /// ``` 93 /// ```
94 FnPtr(Arc<FnSig>), 94 FnPtr(FnSig),
95 95
96 /// The never type `!`. 96 /// The never type `!`.
97 Never, 97 Never,
@@ -128,13 +128,44 @@ impl Substs {
128 pub fn empty() -> Substs { 128 pub fn empty() -> Substs {
129 Substs(Arc::new([])) 129 Substs(Arc::new([]))
130 } 130 }
131
132 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
133 // Without an Arc::make_mut_slice, we can't avoid the clone here:
134 let mut v: Vec<_> = self.0.iter().cloned().collect();
135 for t in &mut v {
136 t.walk_mut(f);
137 }
138 self.0 = v.into();
139 }
131} 140}
132 141
133/// A function signature. 142/// A function signature.
134#[derive(Clone, PartialEq, Eq, Debug)] 143#[derive(Clone, PartialEq, Eq, Debug)]
135pub struct FnSig { 144pub struct FnSig {
136 input: Vec<Ty>, 145 params_and_return: Arc<[Ty]>,
137 output: Ty, 146}
147
148impl FnSig {
149 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig {
150 params.push(ret);
151 FnSig { params_and_return: params.into() }
152 }
153 pub fn params(&self) -> &[Ty] {
154 &self.params_and_return[0..self.params_and_return.len() - 1]
155 }
156
157 pub fn ret(&self) -> &Ty {
158 &self.params_and_return[self.params_and_return.len() - 1]
159 }
160
161 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
162 // Without an Arc::make_mut_slice, we can't avoid the clone here:
163 let mut v: Vec<_> = self.params_and_return.iter().cloned().collect();
164 for t in &mut v {
165 t.walk_mut(f);
166 }
167 self.params_and_return = v.into();
168 }
138} 169}
139 170
140impl Ty { 171impl Ty {
@@ -153,16 +184,16 @@ impl Ty {
153 } 184 }
154 } 185 }
155 Ty::FnPtr(sig) => { 186 Ty::FnPtr(sig) => {
156 for input in &sig.input { 187 for input in sig.params() {
157 input.walk(f); 188 input.walk(f);
158 } 189 }
159 sig.output.walk(f); 190 sig.ret().walk(f);
160 } 191 }
161 Ty::FnDef { substs, sig, .. } => { 192 Ty::FnDef { substs, sig, .. } => {
162 for input in &sig.input { 193 for input in sig.params() {
163 input.walk(f); 194 input.walk(f);
164 } 195 }
165 sig.output.walk(f); 196 sig.ret().walk(f);
166 for t in substs.0.iter() { 197 for t in substs.0.iter() {
167 t.walk(f); 198 t.walk(f);
168 } 199 }
@@ -199,32 +230,14 @@ impl Ty {
199 *ts = v.into(); 230 *ts = v.into();
200 } 231 }
201 Ty::FnPtr(sig) => { 232 Ty::FnPtr(sig) => {
202 let sig_mut = Arc::make_mut(sig); 233 sig.walk_mut(f);
203 for input in &mut sig_mut.input {
204 input.walk_mut(f);
205 }
206 sig_mut.output.walk_mut(f);
207 } 234 }
208 Ty::FnDef { substs, sig, .. } => { 235 Ty::FnDef { substs, sig, .. } => {
209 let sig_mut = Arc::make_mut(sig); 236 sig.walk_mut(f);
210 for input in &mut sig_mut.input { 237 substs.walk_mut(f);
211 input.walk_mut(f);
212 }
213 sig_mut.output.walk_mut(f);
214 // Without an Arc::make_mut_slice, we can't avoid the clone here:
215 let mut v: Vec<_> = substs.0.iter().cloned().collect();
216 for t in &mut v {
217 t.walk_mut(f);
218 }
219 substs.0 = v.into();
220 } 238 }
221 Ty::Adt { substs, .. } => { 239 Ty::Adt { substs, .. } => {
222 // Without an Arc::make_mut_slice, we can't avoid the clone here: 240 substs.walk_mut(f);
223 let mut v: Vec<_> = substs.0.iter().cloned().collect();
224 for t in &mut v {
225 t.walk_mut(f);
226 }
227 substs.0 = v.into();
228 } 241 }
229 Ty::Bool 242 Ty::Bool
230 | Ty::Char 243 | Ty::Char
@@ -328,8 +341,8 @@ impl HirDisplay for Ty {
328 } 341 }
329 Ty::FnPtr(sig) => { 342 Ty::FnPtr(sig) => {
330 write!(f, "fn(")?; 343 write!(f, "fn(")?;
331 f.write_joined(&sig.input, ", ")?; 344 f.write_joined(sig.params(), ", ")?;
332 write!(f, ") -> {}", sig.output.display(f.db))?; 345 write!(f, ") -> {}", sig.ret().display(f.db))?;
333 } 346 }
334 Ty::FnDef { def, substs, sig, .. } => { 347 Ty::FnDef { def, substs, sig, .. } => {
335 let name = match def { 348 let name = match def {
@@ -347,8 +360,8 @@ impl HirDisplay for Ty {
347 write!(f, ">")?; 360 write!(f, ">")?;
348 } 361 }
349 write!(f, "(")?; 362 write!(f, "(")?;
350 f.write_joined(&sig.input, ", ")?; 363 f.write_joined(sig.params(), ", ")?;
351 write!(f, ") -> {}", sig.output.display(f.db))?; 364 write!(f, ") -> {}", sig.ret().display(f.db))?;
352 } 365 }
353 Ty::Adt { def_id, substs, .. } => { 366 Ty::Adt { def_id, substs, .. } => {
354 let name = match def_id { 367 let name = match def_id {