aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/db.rs5
-rw-r--r--crates/ra_hir/src/ty.rs95
-rw-r--r--crates/ra_hir/src/ty/infer.rs31
-rw-r--r--crates/ra_hir/src/ty/lower.rs82
-rw-r--r--crates/ra_hir/src/ty/primitive.rs64
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
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 {
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).
216pub(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.
218pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { 225pub(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
236fn 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.
231fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 247fn 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. 269fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
260fn 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.
285fn 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. 295fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig {
279fn 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.
313fn 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
297fn make_substs(generics: &GenericParams) -> Substs { 323fn 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
12impl UncertainIntTy { 12impl 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
24impl 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)]
33pub enum UncertainFloatTy { 35pub enum UncertainFloatTy {
34 Unknown, 36 Unknown,
@@ -36,13 +38,6 @@ pub enum UncertainFloatTy {
36} 38}
37 39
38impl UncertainFloatTy { 40impl 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
50impl 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)]
56pub enum IntTy { 60pub enum IntTy {
57 Isize, 61 Isize,
@@ -70,22 +74,19 @@ impl fmt::Debug for IntTy {
70 74
71impl fmt::Display for IntTy { 75impl 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
77impl 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
89impl 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
112impl UintTy { 113impl 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
127impl 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
143impl 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)]
150pub enum FloatTy { 148pub enum FloatTy {
151 F32, 149 F32,