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.rs95
1 files changed, 51 insertions, 44 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index f64877f3b..2ea3b341f 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -16,7 +16,7 @@ use std::{fmt, mem};
16 16
17use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase}; 17use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase};
18 18
19pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field}; 19pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field, callable_item_sig};
20pub(crate) use infer::{infer, InferenceResult, InferTy}; 20pub(crate) use infer::{infer, InferenceResult, InferTy};
21use display::{HirDisplay, HirFormatter}; 21use display::{HirDisplay, HirFormatter};
22 22
@@ -77,8 +77,6 @@ pub enum Ty {
77 FnDef { 77 FnDef {
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
81 sig: Arc<FnSig>,
82 /// Substitutions for the generic parameters of the type 80 /// Substitutions for the generic parameters of the type
83 substs: Substs, 81 substs: Substs,
84 }, 82 },
@@ -91,7 +89,7 @@ pub enum Ty {
91 /// fn foo() -> i32 { 1 } 89 /// fn foo() -> i32 { 1 }
92 /// let bar: fn() -> i32 = foo; 90 /// let bar: fn() -> i32 = foo;
93 /// ``` 91 /// ```
94 FnPtr(Arc<FnSig>), 92 FnPtr(FnSig),
95 93
96 /// The never type `!`. 94 /// The never type `!`.
97 Never, 95 Never,
@@ -128,13 +126,44 @@ impl Substs {
128 pub fn empty() -> Substs { 126 pub fn empty() -> Substs {
129 Substs(Arc::new([])) 127 Substs(Arc::new([]))
130 } 128 }
129
130 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
131 // Without an Arc::make_mut_slice, we can't avoid the clone here:
132 let mut v: Vec<_> = self.0.iter().cloned().collect();
133 for t in &mut v {
134 t.walk_mut(f);
135 }
136 self.0 = v.into();
137 }
131} 138}
132 139
133/// A function signature. 140/// A function signature.
134#[derive(Clone, PartialEq, Eq, Debug)] 141#[derive(Clone, PartialEq, Eq, Debug)]
135pub struct FnSig { 142pub struct FnSig {
136 input: Vec<Ty>, 143 params_and_return: Arc<[Ty]>,
137 output: Ty, 144}
145
146impl FnSig {
147 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig {
148 params.push(ret);
149 FnSig { params_and_return: params.into() }
150 }
151 pub fn params(&self) -> &[Ty] {
152 &self.params_and_return[0..self.params_and_return.len() - 1]
153 }
154
155 pub fn ret(&self) -> &Ty {
156 &self.params_and_return[self.params_and_return.len() - 1]
157 }
158
159 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
160 // Without an Arc::make_mut_slice, we can't avoid the clone here:
161 let mut v: Vec<_> = self.params_and_return.iter().cloned().collect();
162 for t in &mut v {
163 t.walk_mut(f);
164 }
165 self.params_and_return = v.into();
166 }
138} 167}
139 168
140impl Ty { 169impl Ty {
@@ -153,16 +182,12 @@ impl Ty {
153 } 182 }
154 } 183 }
155 Ty::FnPtr(sig) => { 184 Ty::FnPtr(sig) => {
156 for input in &sig.input { 185 for input in sig.params() {
157 input.walk(f); 186 input.walk(f);
158 } 187 }
159 sig.output.walk(f); 188 sig.ret().walk(f);
160 } 189 }
161 Ty::FnDef { substs, sig, .. } => { 190 Ty::FnDef { substs, .. } => {
162 for input in &sig.input {
163 input.walk(f);
164 }
165 sig.output.walk(f);
166 for t in substs.0.iter() { 191 for t in substs.0.iter() {
167 t.walk(f); 192 t.walk(f);
168 } 193 }
@@ -199,32 +224,13 @@ impl Ty {
199 *ts = v.into(); 224 *ts = v.into();
200 } 225 }
201 Ty::FnPtr(sig) => { 226 Ty::FnPtr(sig) => {
202 let sig_mut = Arc::make_mut(sig); 227 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 } 228 }
208 Ty::FnDef { substs, sig, .. } => { 229 Ty::FnDef { substs, .. } => {
209 let sig_mut = Arc::make_mut(sig); 230 substs.walk_mut(f);
210 for input in &mut sig_mut.input {
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 } 231 }
221 Ty::Adt { substs, .. } => { 232 Ty::Adt { substs, .. } => {
222 // Without an Arc::make_mut_slice, we can't avoid the clone here: 233 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 } 234 }
229 Ty::Bool 235 Ty::Bool
230 | Ty::Char 236 | Ty::Char
@@ -262,7 +268,7 @@ impl Ty {
262 pub fn apply_substs(self, substs: Substs) -> Ty { 268 pub fn apply_substs(self, substs: Substs) -> Ty {
263 match self { 269 match self {
264 Ty::Adt { def_id, .. } => Ty::Adt { def_id, substs }, 270 Ty::Adt { def_id, .. } => Ty::Adt { def_id, substs },
265 Ty::FnDef { def, sig, .. } => Ty::FnDef { def, sig, substs }, 271 Ty::FnDef { def, .. } => Ty::FnDef { def, substs },
266 _ => self, 272 _ => self,
267 } 273 }
268 } 274 }
@@ -304,8 +310,8 @@ impl HirDisplay for Ty {
304 match self { 310 match self {
305 Ty::Bool => write!(f, "bool")?, 311 Ty::Bool => write!(f, "bool")?,
306 Ty::Char => write!(f, "char")?, 312 Ty::Char => write!(f, "char")?,
307 Ty::Int(t) => write!(f, "{}", t.ty_to_string())?, 313 Ty::Int(t) => write!(f, "{}", t)?,
308 Ty::Float(t) => write!(f, "{}", t.ty_to_string())?, 314 Ty::Float(t) => write!(f, "{}", t)?,
309 Ty::Str => write!(f, "str")?, 315 Ty::Str => write!(f, "str")?,
310 Ty::Slice(t) | Ty::Array(t) => { 316 Ty::Slice(t) | Ty::Array(t) => {
311 write!(f, "[{}]", t.display(f.db))?; 317 write!(f, "[{}]", t.display(f.db))?;
@@ -328,10 +334,11 @@ impl HirDisplay for Ty {
328 } 334 }
329 Ty::FnPtr(sig) => { 335 Ty::FnPtr(sig) => {
330 write!(f, "fn(")?; 336 write!(f, "fn(")?;
331 f.write_joined(&sig.input, ", ")?; 337 f.write_joined(sig.params(), ", ")?;
332 write!(f, ") -> {}", sig.output.display(f.db))?; 338 write!(f, ") -> {}", sig.ret().display(f.db))?;
333 } 339 }
334 Ty::FnDef { def, substs, sig, .. } => { 340 Ty::FnDef { def, substs, .. } => {
341 let sig = f.db.callable_item_signature(*def);
335 let name = match def { 342 let name = match def {
336 CallableDef::Function(ff) => ff.name(f.db), 343 CallableDef::Function(ff) => ff.name(f.db),
337 CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing), 344 CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing),
@@ -347,8 +354,8 @@ impl HirDisplay for Ty {
347 write!(f, ">")?; 354 write!(f, ">")?;
348 } 355 }
349 write!(f, "(")?; 356 write!(f, "(")?;
350 f.write_joined(&sig.input, ", ")?; 357 f.write_joined(sig.params(), ", ")?;
351 write!(f, ") -> {}", sig.output.display(f.db))?; 358 write!(f, ") -> {}", sig.ret().display(f.db))?;
352 } 359 }
353 Ty::Adt { def_id, substs, .. } => { 360 Ty::Adt { def_id, substs, .. } => {
354 let name = match def_id { 361 let name = match def_id {