diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/db.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 95 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 31 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 82 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/primitive.rs | 64 |
5 files changed, 157 insertions, 120 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 21d22aa7f..5ad9547f1 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -12,7 +12,7 @@ use crate::{ | |||
12 | macros::MacroExpansion, | 12 | macros::MacroExpansion, |
13 | module_tree::ModuleTree, | 13 | module_tree::ModuleTree, |
14 | nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, | 14 | nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, |
15 | ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef}, | 15 | ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig}, |
16 | adt::{StructData, EnumData}, | 16 | adt::{StructData, EnumData}, |
17 | impl_block::{ModuleImplBlocks, ImplSourceMap}, | 17 | impl_block::{ModuleImplBlocks, ImplSourceMap}, |
18 | generics::{GenericParams, GenericDef}, | 18 | generics::{GenericParams, GenericDef}, |
@@ -105,6 +105,9 @@ pub trait HirDatabase: PersistentHirDatabase { | |||
105 | #[salsa::invoke(crate::ty::type_for_field)] | 105 | #[salsa::invoke(crate::ty::type_for_field)] |
106 | fn type_for_field(&self, field: StructField) -> Ty; | 106 | fn type_for_field(&self, field: StructField) -> Ty; |
107 | 107 | ||
108 | #[salsa::invoke(crate::ty::callable_item_sig)] | ||
109 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; | ||
110 | |||
108 | #[salsa::invoke(crate::expr::body_with_source_map_query)] | 111 | #[salsa::invoke(crate::expr::body_with_source_map_query)] |
109 | fn body_with_source_map( | 112 | fn body_with_source_map( |
110 | &self, | 113 | &self, |
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 | ||
17 | use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase}; | 17 | use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase}; |
18 | 18 | ||
19 | pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field}; | 19 | pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field, callable_item_sig}; |
20 | pub(crate) use infer::{infer, InferenceResult, InferTy}; | 20 | pub(crate) use infer::{infer, InferenceResult, InferTy}; |
21 | use display::{HirDisplay, HirFormatter}; | 21 | use 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)] |
135 | pub struct FnSig { | 142 | pub struct FnSig { |
136 | input: Vec<Ty>, | 143 | params_and_return: Arc<[Ty]>, |
137 | output: Ty, | 144 | } |
145 | |||
146 | impl 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 | ||
140 | impl Ty { | 169 | impl 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 { |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 268d2c110..c9a5bc7a1 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -724,11 +724,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
724 | Expr::Call { callee, args } => { | 724 | Expr::Call { callee, args } => { |
725 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); | 725 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); |
726 | let (param_tys, ret_ty) = match &callee_ty { | 726 | let (param_tys, ret_ty) = match &callee_ty { |
727 | Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()), | 727 | Ty::FnPtr(sig) => (sig.params().to_vec(), sig.ret().clone()), |
728 | Ty::FnDef { substs, sig, .. } => { | 728 | Ty::FnDef { substs, def, .. } => { |
729 | let ret_ty = sig.output.clone().subst(&substs); | 729 | let sig = self.db.callable_item_signature(*def); |
730 | let ret_ty = sig.ret().clone().subst(&substs); | ||
730 | let param_tys = | 731 | let param_tys = |
731 | sig.input.iter().map(|ty| ty.clone().subst(&substs)).collect(); | 732 | sig.params().iter().map(|ty| ty.clone().subst(&substs)).collect(); |
732 | (param_tys, ret_ty) | 733 | (param_tys, ret_ty) |
733 | } | 734 | } |
734 | _ => { | 735 | _ => { |
@@ -762,19 +763,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
762 | let method_ty = self.insert_type_vars(method_ty); | 763 | let method_ty = self.insert_type_vars(method_ty); |
763 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { | 764 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { |
764 | Ty::FnPtr(sig) => { | 765 | Ty::FnPtr(sig) => { |
765 | if !sig.input.is_empty() { | 766 | if !sig.params().is_empty() { |
766 | (sig.input[0].clone(), sig.input[1..].to_vec(), sig.output.clone()) | 767 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) |
767 | } else { | 768 | } else { |
768 | (Ty::Unknown, Vec::new(), sig.output.clone()) | 769 | (Ty::Unknown, Vec::new(), sig.ret().clone()) |
769 | } | 770 | } |
770 | } | 771 | } |
771 | Ty::FnDef { substs, sig, .. } => { | 772 | Ty::FnDef { substs, def, .. } => { |
772 | let ret_ty = sig.output.clone().subst(&substs); | 773 | let sig = self.db.callable_item_signature(*def); |
773 | 774 | let ret_ty = sig.ret().clone().subst(&substs); | |
774 | if !sig.input.is_empty() { | 775 | |
775 | let mut arg_iter = sig.input.iter().map(|ty| ty.clone().subst(&substs)); | 776 | if !sig.params().is_empty() { |
776 | let receiver_ty = arg_iter.next().unwrap(); | 777 | let mut params_iter = |
777 | (receiver_ty, arg_iter.collect(), ret_ty) | 778 | sig.params().iter().map(|ty| ty.clone().subst(&substs)); |
779 | let receiver_ty = params_iter.next().unwrap(); | ||
780 | (receiver_ty, params_iter.collect(), ret_ty) | ||
778 | } else { | 781 | } else { |
779 | (Ty::Unknown, Vec::new(), ret_ty) | 782 | (Ty::Unknown, Vec::new(), ret_ty) |
780 | } | 783 | } |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index ee4508bb2..278f592d3 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -51,12 +51,10 @@ impl Ty { | |||
51 | } | 51 | } |
52 | TypeRef::Placeholder => Ty::Unknown, | 52 | TypeRef::Placeholder => Ty::Unknown, |
53 | TypeRef::Fn(params) => { | 53 | TypeRef::Fn(params) => { |
54 | let mut inner_tys = | 54 | let inner_tys = |
55 | params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); | 55 | params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); |
56 | let return_ty = | 56 | let sig = FnSig { params_and_return: inner_tys.into() }; |
57 | inner_tys.pop().expect("TypeRef::Fn should always have at least return type"); | 57 | Ty::FnPtr(sig) |
58 | let sig = FnSig { input: inner_tys, output: return_ty }; | ||
59 | Ty::FnPtr(Arc::new(sig)) | ||
60 | } | 58 | } |
61 | TypeRef::Error => Ty::Unknown, | 59 | TypeRef::Error => Ty::Unknown, |
62 | } | 60 | } |
@@ -214,6 +212,15 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace | |||
214 | } | 212 | } |
215 | } | 213 | } |
216 | 214 | ||
215 | /// Build the signature of a callable item (function, struct or enum variant). | ||
216 | pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { | ||
217 | match def { | ||
218 | CallableDef::Function(f) => fn_sig_for_fn(db, f), | ||
219 | CallableDef::Struct(s) => fn_sig_for_struct_constructor(db, s), | ||
220 | CallableDef::EnumVariant(e) => fn_sig_for_enum_variant_constructor(db, e), | ||
221 | } | ||
222 | } | ||
223 | |||
217 | /// Build the type of a specific field of a struct or enum variant. | 224 | /// Build the type of a specific field of a struct or enum variant. |
218 | pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | 225 | pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { |
219 | let parent_def = field.parent_def(db); | 226 | let parent_def = field.parent_def(db); |
@@ -226,18 +233,21 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | |||
226 | Ty::from_hir(db, &resolver, type_ref) | 233 | Ty::from_hir(db, &resolver, type_ref) |
227 | } | 234 | } |
228 | 235 | ||
236 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | ||
237 | let signature = def.signature(db); | ||
238 | let resolver = def.resolver(db); | ||
239 | let params = | ||
240 | signature.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); | ||
241 | let ret = Ty::from_hir(db, &resolver, signature.ret_type()); | ||
242 | FnSig::from_params_and_return(params, ret) | ||
243 | } | ||
244 | |||
229 | /// Build the declared type of a function. This should not need to look at the | 245 | /// Build the declared type of a function. This should not need to look at the |
230 | /// function body. | 246 | /// function body. |
231 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | 247 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { |
232 | let signature = def.signature(db); | ||
233 | let resolver = def.resolver(db); | ||
234 | let generics = def.generic_params(db); | 248 | let generics = def.generic_params(db); |
235 | let input = | ||
236 | signature.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); | ||
237 | let output = Ty::from_hir(db, &resolver, signature.ret_type()); | ||
238 | let sig = Arc::new(FnSig { input, output }); | ||
239 | let substs = make_substs(&generics); | 249 | let substs = make_substs(&generics); |
240 | Ty::FnDef { def: def.into(), sig, substs } | 250 | Ty::FnDef { def: def.into(), substs } |
241 | } | 251 | } |
242 | 252 | ||
243 | /// Build the declared type of a const. | 253 | /// Build the declared type of a const. |
@@ -256,42 +266,58 @@ fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { | |||
256 | Ty::from_hir(db, &resolver, signature.type_ref()) | 266 | Ty::from_hir(db, &resolver, signature.type_ref()) |
257 | } | 267 | } |
258 | 268 | ||
259 | /// Build the type of a tuple struct constructor. | 269 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { |
260 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | ||
261 | let var_data = def.variant_data(db); | 270 | let var_data = def.variant_data(db); |
262 | let fields = match var_data.fields() { | 271 | let fields = match var_data.fields() { |
263 | Some(fields) => fields, | 272 | Some(fields) => fields, |
264 | None => return type_for_struct(db, def), // Unit struct | 273 | None => panic!("fn_sig_for_struct_constructor called on unit struct"), |
265 | }; | 274 | }; |
266 | let resolver = def.resolver(db); | 275 | let resolver = def.resolver(db); |
267 | let generics = def.generic_params(db); | 276 | let params = fields |
268 | let input = fields | ||
269 | .iter() | 277 | .iter() |
270 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 278 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) |
271 | .collect::<Vec<_>>(); | 279 | .collect::<Vec<_>>(); |
272 | let output = type_for_struct(db, def); | 280 | let ret = type_for_struct(db, def); |
273 | let sig = Arc::new(FnSig { input, output }); | 281 | FnSig::from_params_and_return(params, ret) |
282 | } | ||
283 | |||
284 | /// Build the type of a tuple struct constructor. | ||
285 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | ||
286 | let var_data = def.variant_data(db); | ||
287 | if var_data.fields().is_none() { | ||
288 | return type_for_struct(db, def); // Unit struct | ||
289 | } | ||
290 | let generics = def.generic_params(db); | ||
274 | let substs = make_substs(&generics); | 291 | let substs = make_substs(&generics); |
275 | Ty::FnDef { def: def.into(), sig, substs } | 292 | Ty::FnDef { def: def.into(), substs } |
276 | } | 293 | } |
277 | 294 | ||
278 | /// Build the type of a tuple enum variant constructor. | 295 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { |
279 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { | ||
280 | let var_data = def.variant_data(db); | 296 | let var_data = def.variant_data(db); |
281 | let fields = match var_data.fields() { | 297 | let fields = match var_data.fields() { |
282 | Some(fields) => fields, | 298 | Some(fields) => fields, |
283 | None => return type_for_enum(db, def.parent_enum(db)), // Unit variant | 299 | None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"), |
284 | }; | 300 | }; |
285 | let resolver = def.parent_enum(db).resolver(db); | 301 | let resolver = def.parent_enum(db).resolver(db); |
286 | let generics = def.parent_enum(db).generic_params(db); | 302 | let params = fields |
287 | let input = fields | ||
288 | .iter() | 303 | .iter() |
289 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 304 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) |
290 | .collect::<Vec<_>>(); | 305 | .collect::<Vec<_>>(); |
306 | let generics = def.parent_enum(db).generic_params(db); | ||
307 | let substs = make_substs(&generics); | ||
308 | let ret = type_for_enum(db, def.parent_enum(db)).subst(&substs); | ||
309 | FnSig::from_params_and_return(params, ret) | ||
310 | } | ||
311 | |||
312 | /// Build the type of a tuple enum variant constructor. | ||
313 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { | ||
314 | let var_data = def.variant_data(db); | ||
315 | if var_data.fields().is_none() { | ||
316 | return type_for_enum(db, def.parent_enum(db)); // Unit variant | ||
317 | } | ||
318 | let generics = def.parent_enum(db).generic_params(db); | ||
291 | let substs = make_substs(&generics); | 319 | let substs = make_substs(&generics); |
292 | let output = type_for_enum(db, def.parent_enum(db)).subst(&substs); | 320 | Ty::FnDef { def: def.into(), substs } |
293 | let sig = Arc::new(FnSig { input, output }); | ||
294 | Ty::FnDef { def: def.into(), sig, substs } | ||
295 | } | 321 | } |
296 | 322 | ||
297 | fn make_substs(generics: &GenericParams) -> Substs { | 323 | fn make_substs(generics: &GenericParams) -> Substs { |
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 5741ca90d..30aeac48e 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs | |||
@@ -10,14 +10,6 @@ pub enum UncertainIntTy { | |||
10 | } | 10 | } |
11 | 11 | ||
12 | impl UncertainIntTy { | 12 | impl UncertainIntTy { |
13 | pub fn ty_to_string(&self) -> &'static str { | ||
14 | match *self { | ||
15 | UncertainIntTy::Unknown => "{integer}", | ||
16 | UncertainIntTy::Signed(ty) => ty.ty_to_string(), | ||
17 | UncertainIntTy::Unsigned(ty) => ty.ty_to_string(), | ||
18 | } | ||
19 | } | ||
20 | |||
21 | pub fn from_name(name: &Name) -> Option<UncertainIntTy> { | 13 | pub fn from_name(name: &Name) -> Option<UncertainIntTy> { |
22 | if let Some(ty) = IntTy::from_name(name) { | 14 | if let Some(ty) = IntTy::from_name(name) { |
23 | Some(UncertainIntTy::Signed(ty)) | 15 | Some(UncertainIntTy::Signed(ty)) |
@@ -29,6 +21,16 @@ impl UncertainIntTy { | |||
29 | } | 21 | } |
30 | } | 22 | } |
31 | 23 | ||
24 | impl fmt::Display for UncertainIntTy { | ||
25 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
26 | match *self { | ||
27 | UncertainIntTy::Unknown => write!(f, "{{integer}}"), | ||
28 | UncertainIntTy::Signed(ty) => write!(f, "{}", ty), | ||
29 | UncertainIntTy::Unsigned(ty) => write!(f, "{}", ty), | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | |||
32 | #[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)] | 34 | #[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)] |
33 | pub enum UncertainFloatTy { | 35 | pub enum UncertainFloatTy { |
34 | Unknown, | 36 | Unknown, |
@@ -36,13 +38,6 @@ pub enum UncertainFloatTy { | |||
36 | } | 38 | } |
37 | 39 | ||
38 | impl UncertainFloatTy { | 40 | impl UncertainFloatTy { |
39 | pub fn ty_to_string(&self) -> &'static str { | ||
40 | match *self { | ||
41 | UncertainFloatTy::Unknown => "{float}", | ||
42 | UncertainFloatTy::Known(ty) => ty.ty_to_string(), | ||
43 | } | ||
44 | } | ||
45 | |||
46 | pub fn from_name(name: &Name) -> Option<UncertainFloatTy> { | 41 | pub fn from_name(name: &Name) -> Option<UncertainFloatTy> { |
47 | if let Some(ty) = FloatTy::from_name(name) { | 42 | if let Some(ty) = FloatTy::from_name(name) { |
48 | Some(UncertainFloatTy::Known(ty)) | 43 | Some(UncertainFloatTy::Known(ty)) |
@@ -52,6 +47,15 @@ impl UncertainFloatTy { | |||
52 | } | 47 | } |
53 | } | 48 | } |
54 | 49 | ||
50 | impl fmt::Display for UncertainFloatTy { | ||
51 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
52 | match *self { | ||
53 | UncertainFloatTy::Unknown => write!(f, "{{float}}"), | ||
54 | UncertainFloatTy::Known(ty) => write!(f, "{}", ty), | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
55 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] | 59 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] |
56 | pub enum IntTy { | 60 | pub enum IntTy { |
57 | Isize, | 61 | Isize, |
@@ -70,22 +74,19 @@ impl fmt::Debug for IntTy { | |||
70 | 74 | ||
71 | impl fmt::Display for IntTy { | 75 | impl fmt::Display for IntTy { |
72 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 76 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
73 | write!(f, "{}", self.ty_to_string()) | 77 | let s = match *self { |
74 | } | ||
75 | } | ||
76 | |||
77 | impl IntTy { | ||
78 | pub fn ty_to_string(&self) -> &'static str { | ||
79 | match *self { | ||
80 | IntTy::Isize => "isize", | 78 | IntTy::Isize => "isize", |
81 | IntTy::I8 => "i8", | 79 | IntTy::I8 => "i8", |
82 | IntTy::I16 => "i16", | 80 | IntTy::I16 => "i16", |
83 | IntTy::I32 => "i32", | 81 | IntTy::I32 => "i32", |
84 | IntTy::I64 => "i64", | 82 | IntTy::I64 => "i64", |
85 | IntTy::I128 => "i128", | 83 | IntTy::I128 => "i128", |
86 | } | 84 | }; |
85 | write!(f, "{}", s) | ||
87 | } | 86 | } |
87 | } | ||
88 | 88 | ||
89 | impl IntTy { | ||
89 | pub fn from_name(name: &Name) -> Option<IntTy> { | 90 | pub fn from_name(name: &Name) -> Option<IntTy> { |
90 | match name.as_known_name()? { | 91 | match name.as_known_name()? { |
91 | KnownName::Isize => Some(IntTy::Isize), | 92 | KnownName::Isize => Some(IntTy::Isize), |
@@ -109,18 +110,21 @@ pub enum UintTy { | |||
109 | U128, | 110 | U128, |
110 | } | 111 | } |
111 | 112 | ||
112 | impl UintTy { | 113 | impl fmt::Display for UintTy { |
113 | pub fn ty_to_string(&self) -> &'static str { | 114 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
114 | match *self { | 115 | let s = match *self { |
115 | UintTy::Usize => "usize", | 116 | UintTy::Usize => "usize", |
116 | UintTy::U8 => "u8", | 117 | UintTy::U8 => "u8", |
117 | UintTy::U16 => "u16", | 118 | UintTy::U16 => "u16", |
118 | UintTy::U32 => "u32", | 119 | UintTy::U32 => "u32", |
119 | UintTy::U64 => "u64", | 120 | UintTy::U64 => "u64", |
120 | UintTy::U128 => "u128", | 121 | UintTy::U128 => "u128", |
121 | } | 122 | }; |
123 | write!(f, "{}", s) | ||
122 | } | 124 | } |
125 | } | ||
123 | 126 | ||
127 | impl UintTy { | ||
124 | pub fn from_name(name: &Name) -> Option<UintTy> { | 128 | pub fn from_name(name: &Name) -> Option<UintTy> { |
125 | match name.as_known_name()? { | 129 | match name.as_known_name()? { |
126 | KnownName::Usize => Some(UintTy::Usize), | 130 | KnownName::Usize => Some(UintTy::Usize), |
@@ -140,12 +144,6 @@ impl fmt::Debug for UintTy { | |||
140 | } | 144 | } |
141 | } | 145 | } |
142 | 146 | ||
143 | impl fmt::Display for UintTy { | ||
144 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
145 | write!(f, "{}", self.ty_to_string()) | ||
146 | } | ||
147 | } | ||
148 | |||
149 | #[derive(Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord)] | 147 | #[derive(Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord)] |
150 | pub enum FloatTy { | 148 | pub enum FloatTy { |
151 | F32, | 149 | F32, |