diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 427 |
1 files changed, 237 insertions, 190 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index fa46ddfe9..85d4dc05c 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -14,7 +14,7 @@ | |||
14 | //! rustc. | 14 | //! rustc. |
15 | 15 | ||
16 | mod autoderef; | 16 | mod autoderef; |
17 | mod primitive; | 17 | pub(crate) mod primitive; |
18 | #[cfg(test)] | 18 | #[cfg(test)] |
19 | mod tests; | 19 | mod tests; |
20 | pub(crate) mod method_resolution; | 20 | pub(crate) mod method_resolution; |
@@ -30,25 +30,15 @@ use ra_arena::map::ArenaMap; | |||
30 | use join_to_string::join; | 30 | use join_to_string::join; |
31 | use rustc_hash::FxHashMap; | 31 | use rustc_hash::FxHashMap; |
32 | 32 | ||
33 | use ra_db::Cancelable; | ||
34 | |||
35 | use crate::{ | 33 | use crate::{ |
36 | Def, DefId, Module, Function, Struct, Enum, EnumVariant, Path, Name, ImplBlock, | 34 | Def, DefId, Module, Function, Struct, Enum, EnumVariant, Path, Name, ImplBlock, |
37 | FnSignature, FnScopes, | 35 | FnSignature, FnScopes, |
38 | db::HirDatabase, | 36 | db::HirDatabase, |
39 | type_ref::{TypeRef, Mutability}, | 37 | type_ref::{TypeRef, Mutability}, |
40 | name::KnownName, | 38 | name::KnownName, |
41 | expr::{Body, Expr, ExprId, PatId, UnaryOp, BinaryOp, Statement}, | 39 | expr::{Body, Expr, Literal, ExprId, PatId, UnaryOp, BinaryOp, Statement}, |
42 | }; | 40 | }; |
43 | 41 | ||
44 | fn transpose<T>(x: Cancelable<Option<T>>) -> Option<Cancelable<T>> { | ||
45 | match x { | ||
46 | Ok(Some(t)) => Some(Ok(t)), | ||
47 | Ok(None) => None, | ||
48 | Err(e) => Some(Err(e)), | ||
49 | } | ||
50 | } | ||
51 | |||
52 | /// The ID of a type variable. | 42 | /// The ID of a type variable. |
53 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | 43 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] |
54 | pub struct TypeVarId(u32); | 44 | pub struct TypeVarId(u32); |
@@ -107,13 +97,35 @@ impl UnifyValue for TypeVarValue { | |||
107 | } | 97 | } |
108 | } | 98 | } |
109 | 99 | ||
110 | /// The kinds of placeholders we need during type inference. Currently, we only | 100 | /// The kinds of placeholders we need during type inference. There's separate |
111 | /// have type variables; in the future, we will probably also need int and float | 101 | /// values for general types, and for integer and float variables. The latter |
112 | /// variables, for inference of literal values (e.g. `100` could be one of | 102 | /// two are used for inference of literal values (e.g. `100` could be one of |
113 | /// several integer types). | 103 | /// several integer types). |
114 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 104 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] |
115 | pub enum InferTy { | 105 | pub enum InferTy { |
116 | TypeVar(TypeVarId), | 106 | TypeVar(TypeVarId), |
107 | IntVar(TypeVarId), | ||
108 | FloatVar(TypeVarId), | ||
109 | } | ||
110 | |||
111 | impl InferTy { | ||
112 | fn to_inner(self) -> TypeVarId { | ||
113 | match self { | ||
114 | InferTy::TypeVar(ty) | InferTy::IntVar(ty) | InferTy::FloatVar(ty) => ty, | ||
115 | } | ||
116 | } | ||
117 | |||
118 | fn fallback_value(self) -> Ty { | ||
119 | match self { | ||
120 | InferTy::TypeVar(..) => Ty::Unknown, | ||
121 | InferTy::IntVar(..) => { | ||
122 | Ty::Int(primitive::UncertainIntTy::Signed(primitive::IntTy::I32)) | ||
123 | } | ||
124 | InferTy::FloatVar(..) => { | ||
125 | Ty::Float(primitive::UncertainFloatTy::Known(primitive::FloatTy::F64)) | ||
126 | } | ||
127 | } | ||
128 | } | ||
117 | } | 129 | } |
118 | 130 | ||
119 | /// When inferring an expression, we propagate downward whatever type hint we | 131 | /// When inferring an expression, we propagate downward whatever type hint we |
@@ -151,14 +163,11 @@ pub enum Ty { | |||
151 | /// (a non-surrogate code point). Written as `char`. | 163 | /// (a non-surrogate code point). Written as `char`. |
152 | Char, | 164 | Char, |
153 | 165 | ||
154 | /// A primitive signed integer type. For example, `i32`. | 166 | /// A primitive integer type. For example, `i32`. |
155 | Int(primitive::IntTy), | 167 | Int(primitive::UncertainIntTy), |
156 | |||
157 | /// A primitive unsigned integer type. For example, `u32`. | ||
158 | Uint(primitive::UintTy), | ||
159 | 168 | ||
160 | /// A primitive floating-point type. For example, `f64`. | 169 | /// A primitive floating-point type. For example, `f64`. |
161 | Float(primitive::FloatTy), | 170 | Float(primitive::UncertainFloatTy), |
162 | 171 | ||
163 | /// Structures, enumerations and unions. | 172 | /// Structures, enumerations and unions. |
164 | Adt { | 173 | Adt { |
@@ -198,8 +207,9 @@ pub enum Ty { | |||
198 | // above function pointer type. Once we implement generics, we will probably | 207 | // above function pointer type. Once we implement generics, we will probably |
199 | // need this as well. | 208 | // need this as well. |
200 | 209 | ||
201 | // A trait, defined with `dyn trait`. | 210 | // A trait, defined with `dyn Trait`. |
202 | // Dynamic(), | 211 | // Dynamic(), |
212 | |||
203 | // The anonymous type of a closure. Used to represent the type of | 213 | // The anonymous type of a closure. Used to represent the type of |
204 | // `|a| a`. | 214 | // `|a| a`. |
205 | // Closure(DefId, ClosureSubsts<'tcx>), | 215 | // Closure(DefId, ClosureSubsts<'tcx>), |
@@ -251,28 +261,28 @@ impl Ty { | |||
251 | module: &Module, | 261 | module: &Module, |
252 | impl_block: Option<&ImplBlock>, | 262 | impl_block: Option<&ImplBlock>, |
253 | type_ref: &TypeRef, | 263 | type_ref: &TypeRef, |
254 | ) -> Cancelable<Self> { | 264 | ) -> Self { |
255 | Ok(match type_ref { | 265 | match type_ref { |
256 | TypeRef::Never => Ty::Never, | 266 | TypeRef::Never => Ty::Never, |
257 | TypeRef::Tuple(inner) => { | 267 | TypeRef::Tuple(inner) => { |
258 | let inner_tys = inner | 268 | let inner_tys = inner |
259 | .iter() | 269 | .iter() |
260 | .map(|tr| Ty::from_hir(db, module, impl_block, tr)) | 270 | .map(|tr| Ty::from_hir(db, module, impl_block, tr)) |
261 | .collect::<Cancelable<Vec<_>>>()?; | 271 | .collect::<Vec<_>>(); |
262 | Ty::Tuple(inner_tys.into()) | 272 | Ty::Tuple(inner_tys.into()) |
263 | } | 273 | } |
264 | TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, path)?, | 274 | TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, path), |
265 | TypeRef::RawPtr(inner, mutability) => { | 275 | TypeRef::RawPtr(inner, mutability) => { |
266 | let inner_ty = Ty::from_hir(db, module, impl_block, inner)?; | 276 | let inner_ty = Ty::from_hir(db, module, impl_block, inner); |
267 | Ty::RawPtr(Arc::new(inner_ty), *mutability) | 277 | Ty::RawPtr(Arc::new(inner_ty), *mutability) |
268 | } | 278 | } |
269 | TypeRef::Array(_inner) => Ty::Unknown, // TODO | 279 | TypeRef::Array(_inner) => Ty::Unknown, // TODO |
270 | TypeRef::Slice(inner) => { | 280 | TypeRef::Slice(inner) => { |
271 | let inner_ty = Ty::from_hir(db, module, impl_block, inner)?; | 281 | let inner_ty = Ty::from_hir(db, module, impl_block, inner); |
272 | Ty::Slice(Arc::new(inner_ty)) | 282 | Ty::Slice(Arc::new(inner_ty)) |
273 | } | 283 | } |
274 | TypeRef::Reference(inner, mutability) => { | 284 | TypeRef::Reference(inner, mutability) => { |
275 | let inner_ty = Ty::from_hir(db, module, impl_block, inner)?; | 285 | let inner_ty = Ty::from_hir(db, module, impl_block, inner); |
276 | Ty::Ref(Arc::new(inner_ty), *mutability) | 286 | Ty::Ref(Arc::new(inner_ty), *mutability) |
277 | } | 287 | } |
278 | TypeRef::Placeholder => Ty::Unknown, | 288 | TypeRef::Placeholder => Ty::Unknown, |
@@ -280,7 +290,7 @@ impl Ty { | |||
280 | let mut inner_tys = params | 290 | let mut inner_tys = params |
281 | .iter() | 291 | .iter() |
282 | .map(|tr| Ty::from_hir(db, module, impl_block, tr)) | 292 | .map(|tr| Ty::from_hir(db, module, impl_block, tr)) |
283 | .collect::<Cancelable<Vec<_>>>()?; | 293 | .collect::<Vec<_>>(); |
284 | let return_ty = inner_tys | 294 | let return_ty = inner_tys |
285 | .pop() | 295 | .pop() |
286 | .expect("TypeRef::Fn should always have at least return type"); | 296 | .expect("TypeRef::Fn should always have at least return type"); |
@@ -291,7 +301,7 @@ impl Ty { | |||
291 | Ty::FnPtr(Arc::new(sig)) | 301 | Ty::FnPtr(Arc::new(sig)) |
292 | } | 302 | } |
293 | TypeRef::Error => Ty::Unknown, | 303 | TypeRef::Error => Ty::Unknown, |
294 | }) | 304 | } |
295 | } | 305 | } |
296 | 306 | ||
297 | pub(crate) fn from_hir_opt( | 307 | pub(crate) fn from_hir_opt( |
@@ -299,10 +309,8 @@ impl Ty { | |||
299 | module: &Module, | 309 | module: &Module, |
300 | impl_block: Option<&ImplBlock>, | 310 | impl_block: Option<&ImplBlock>, |
301 | type_ref: Option<&TypeRef>, | 311 | type_ref: Option<&TypeRef>, |
302 | ) -> Cancelable<Self> { | 312 | ) -> Self { |
303 | type_ref | 313 | type_ref.map_or(Ty::Unknown, |t| Ty::from_hir(db, module, impl_block, t)) |
304 | .map(|t| Ty::from_hir(db, module, impl_block, t)) | ||
305 | .unwrap_or(Ok(Ty::Unknown)) | ||
306 | } | 314 | } |
307 | 315 | ||
308 | pub(crate) fn from_hir_path( | 316 | pub(crate) fn from_hir_path( |
@@ -310,33 +318,31 @@ impl Ty { | |||
310 | module: &Module, | 318 | module: &Module, |
311 | impl_block: Option<&ImplBlock>, | 319 | impl_block: Option<&ImplBlock>, |
312 | path: &Path, | 320 | path: &Path, |
313 | ) -> Cancelable<Self> { | 321 | ) -> Self { |
314 | if let Some(name) = path.as_ident() { | 322 | if let Some(name) = path.as_ident() { |
315 | if let Some(KnownName::Bool) = name.as_known_name() { | 323 | if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) { |
316 | return Ok(Ty::Bool); | 324 | return Ty::Int(int_ty); |
317 | } else if let Some(KnownName::Char) = name.as_known_name() { | 325 | } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { |
318 | return Ok(Ty::Char); | 326 | return Ty::Float(float_ty); |
319 | } else if let Some(KnownName::Str) = name.as_known_name() { | ||
320 | return Ok(Ty::Str); | ||
321 | } else if let Some(int_ty) = primitive::IntTy::from_name(name) { | ||
322 | return Ok(Ty::Int(int_ty)); | ||
323 | } else if let Some(uint_ty) = primitive::UintTy::from_name(name) { | ||
324 | return Ok(Ty::Uint(uint_ty)); | ||
325 | } else if let Some(float_ty) = primitive::FloatTy::from_name(name) { | ||
326 | return Ok(Ty::Float(float_ty)); | ||
327 | } else if name.as_known_name() == Some(KnownName::SelfType) { | 327 | } else if name.as_known_name() == Some(KnownName::SelfType) { |
328 | return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type())); | 328 | return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type())); |
329 | } else if let Some(known) = name.as_known_name() { | ||
330 | match known { | ||
331 | KnownName::Bool => return Ty::Bool, | ||
332 | KnownName::Char => return Ty::Char, | ||
333 | KnownName::Str => return Ty::Str, | ||
334 | _ => {} | ||
335 | } | ||
329 | } | 336 | } |
330 | } | 337 | } |
331 | 338 | ||
332 | // Resolve in module (in type namespace) | 339 | // Resolve in module (in type namespace) |
333 | let resolved = if let Some(r) = module.resolve_path(db, path)?.take_types() { | 340 | let resolved = if let Some(r) = module.resolve_path(db, path).take_types() { |
334 | r | 341 | r |
335 | } else { | 342 | } else { |
336 | return Ok(Ty::Unknown); | 343 | return Ty::Unknown; |
337 | }; | 344 | }; |
338 | let ty = db.type_for_def(resolved)?; | 345 | db.type_for_def(resolved) |
339 | Ok(ty) | ||
340 | } | 346 | } |
341 | 347 | ||
342 | pub fn unit() -> Self { | 348 | pub fn unit() -> Self { |
@@ -392,7 +398,6 @@ impl fmt::Display for Ty { | |||
392 | Ty::Bool => write!(f, "bool"), | 398 | Ty::Bool => write!(f, "bool"), |
393 | Ty::Char => write!(f, "char"), | 399 | Ty::Char => write!(f, "char"), |
394 | Ty::Int(t) => write!(f, "{}", t.ty_to_string()), | 400 | Ty::Int(t) => write!(f, "{}", t.ty_to_string()), |
395 | Ty::Uint(t) => write!(f, "{}", t.ty_to_string()), | ||
396 | Ty::Float(t) => write!(f, "{}", t.ty_to_string()), | 401 | Ty::Float(t) => write!(f, "{}", t.ty_to_string()), |
397 | Ty::Str => write!(f, "str"), | 402 | Ty::Str => write!(f, "str"), |
398 | Ty::Slice(t) => write!(f, "[{}]", t), | 403 | Ty::Slice(t) => write!(f, "[{}]", t), |
@@ -427,47 +432,47 @@ impl fmt::Display for Ty { | |||
427 | 432 | ||
428 | /// Compute the declared type of a function. This should not need to look at the | 433 | /// Compute the declared type of a function. This should not need to look at the |
429 | /// function body. | 434 | /// function body. |
430 | fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> { | 435 | fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty { |
431 | let signature = f.signature(db); | 436 | let signature = f.signature(db); |
432 | let module = f.module(db)?; | 437 | let module = f.module(db); |
433 | let impl_block = f.impl_block(db)?; | 438 | let impl_block = f.impl_block(db); |
434 | // TODO we ignore type parameters for now | 439 | // TODO we ignore type parameters for now |
435 | let input = signature | 440 | let input = signature |
436 | .params() | 441 | .params() |
437 | .iter() | 442 | .iter() |
438 | .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), tr)) | 443 | .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), tr)) |
439 | .collect::<Cancelable<Vec<_>>>()?; | 444 | .collect::<Vec<_>>(); |
440 | let output = Ty::from_hir(db, &module, impl_block.as_ref(), signature.ret_type())?; | 445 | let output = Ty::from_hir(db, &module, impl_block.as_ref(), signature.ret_type()); |
441 | let sig = FnSig { input, output }; | 446 | let sig = FnSig { input, output }; |
442 | Ok(Ty::FnPtr(Arc::new(sig))) | 447 | Ty::FnPtr(Arc::new(sig)) |
443 | } | 448 | } |
444 | 449 | ||
445 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Cancelable<Ty> { | 450 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { |
446 | Ok(Ty::Adt { | 451 | Ty::Adt { |
447 | def_id: s.def_id(), | 452 | def_id: s.def_id(), |
448 | name: s.name(db)?.unwrap_or_else(Name::missing), | 453 | name: s.name(db).unwrap_or_else(Name::missing), |
449 | }) | 454 | } |
450 | } | 455 | } |
451 | 456 | ||
452 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Cancelable<Ty> { | 457 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { |
453 | Ok(Ty::Adt { | 458 | Ty::Adt { |
454 | def_id: s.def_id(), | 459 | def_id: s.def_id(), |
455 | name: s.name(db)?.unwrap_or_else(Name::missing), | 460 | name: s.name(db).unwrap_or_else(Name::missing), |
456 | }) | 461 | } |
457 | } | 462 | } |
458 | 463 | ||
459 | pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> Cancelable<Ty> { | 464 | pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> Ty { |
460 | let enum_parent = ev.parent_enum(db)?; | 465 | let enum_parent = ev.parent_enum(db); |
461 | 466 | ||
462 | type_for_enum(db, enum_parent) | 467 | type_for_enum(db, enum_parent) |
463 | } | 468 | } |
464 | 469 | ||
465 | pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ty> { | 470 | pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty { |
466 | let def = def_id.resolve(db)?; | 471 | let def = def_id.resolve(db); |
467 | match def { | 472 | match def { |
468 | Def::Module(..) => { | 473 | Def::Module(..) => { |
469 | log::debug!("trying to get type for module {:?}", def_id); | 474 | log::debug!("trying to get type for module {:?}", def_id); |
470 | Ok(Ty::Unknown) | 475 | Ty::Unknown |
471 | } | 476 | } |
472 | Def::Function(f) => type_for_fn(db, f), | 477 | Def::Function(f) => type_for_fn(db, f), |
473 | Def::Struct(s) => type_for_struct(db, s), | 478 | Def::Struct(s) => type_for_struct(db, s), |
@@ -479,35 +484,26 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<T | |||
479 | def_id, | 484 | def_id, |
480 | def | 485 | def |
481 | ); | 486 | ); |
482 | Ok(Ty::Unknown) | 487 | Ty::Unknown |
483 | } | 488 | } |
484 | } | 489 | } |
485 | } | 490 | } |
486 | 491 | ||
487 | pub(super) fn type_for_field( | 492 | pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Option<Ty> { |
488 | db: &impl HirDatabase, | 493 | let def = def_id.resolve(db); |
489 | def_id: DefId, | ||
490 | field: Name, | ||
491 | ) -> Cancelable<Option<Ty>> { | ||
492 | let def = def_id.resolve(db)?; | ||
493 | let variant_data = match def { | 494 | let variant_data = match def { |
494 | Def::Struct(s) => s.variant_data(db)?, | 495 | Def::Struct(s) => s.variant_data(db), |
495 | Def::EnumVariant(ev) => ev.variant_data(db)?, | 496 | Def::EnumVariant(ev) => ev.variant_data(db), |
496 | // TODO: unions | 497 | // TODO: unions |
497 | _ => panic!( | 498 | _ => panic!( |
498 | "trying to get type for field in non-struct/variant {:?}", | 499 | "trying to get type for field in non-struct/variant {:?}", |
499 | def_id | 500 | def_id |
500 | ), | 501 | ), |
501 | }; | 502 | }; |
502 | let module = def_id.module(db)?; | 503 | let module = def_id.module(db); |
503 | let impl_block = def_id.impl_block(db)?; | 504 | let impl_block = def_id.impl_block(db); |
504 | let type_ref = ctry!(variant_data.get_field_type_ref(&field)); | 505 | let type_ref = variant_data.get_field_type_ref(&field)?; |
505 | Ok(Some(Ty::from_hir( | 506 | Some(Ty::from_hir(db, &module, impl_block.as_ref(), &type_ref)) |
506 | db, | ||
507 | &module, | ||
508 | impl_block.as_ref(), | ||
509 | &type_ref, | ||
510 | )?)) | ||
511 | } | 507 | } |
512 | 508 | ||
513 | /// The result of type inference: A mapping from expressions and patterns to types. | 509 | /// The result of type inference: A mapping from expressions and patterns to types. |
@@ -587,7 +583,7 @@ fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { | |||
587 | | BinaryOp::BitwiseAnd | 583 | | BinaryOp::BitwiseAnd |
588 | | BinaryOp::BitwiseOr | 584 | | BinaryOp::BitwiseOr |
589 | | BinaryOp::BitwiseXor => match rhs_ty { | 585 | | BinaryOp::BitwiseXor => match rhs_ty { |
590 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => rhs_ty, | 586 | Ty::Int(..) | Ty::Float(..) => rhs_ty, |
591 | _ => Ty::Unknown, | 587 | _ => Ty::Unknown, |
592 | }, | 588 | }, |
593 | BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown, | 589 | BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown, |
@@ -598,7 +594,7 @@ fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | |||
598 | match op { | 594 | match op { |
599 | BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool, | 595 | BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool, |
600 | BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { | 596 | BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { |
601 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty, | 597 | Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty, |
602 | _ => Ty::Unknown, | 598 | _ => Ty::Unknown, |
603 | }, | 599 | }, |
604 | BinaryOp::LesserEqualTest | 600 | BinaryOp::LesserEqualTest |
@@ -625,7 +621,7 @@ fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | |||
625 | | BinaryOp::BitwiseAnd | 621 | | BinaryOp::BitwiseAnd |
626 | | BinaryOp::BitwiseOr | 622 | | BinaryOp::BitwiseOr |
627 | | BinaryOp::BitwiseXor => match lhs_ty { | 623 | | BinaryOp::BitwiseXor => match lhs_ty { |
628 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => lhs_ty, | 624 | Ty::Int(..) | Ty::Float(..) => lhs_ty, |
629 | _ => Ty::Unknown, | 625 | _ => Ty::Unknown, |
630 | }, | 626 | }, |
631 | _ => Ty::Unknown, | 627 | _ => Ty::Unknown, |
@@ -684,7 +680,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
684 | self.type_of_pat.insert(pat, ty); | 680 | self.type_of_pat.insert(pat, ty); |
685 | } | 681 | } |
686 | 682 | ||
687 | fn make_ty(&self, type_ref: &TypeRef) -> Cancelable<Ty> { | 683 | fn make_ty(&self, type_ref: &TypeRef) -> Ty { |
688 | Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref) | 684 | Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref) |
689 | } | 685 | } |
690 | 686 | ||
@@ -695,13 +691,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
695 | match (&*ty1, &*ty2) { | 691 | match (&*ty1, &*ty2) { |
696 | (Ty::Unknown, ..) => true, | 692 | (Ty::Unknown, ..) => true, |
697 | (.., Ty::Unknown) => true, | 693 | (.., Ty::Unknown) => true, |
698 | (Ty::Bool, _) | 694 | (Ty::Int(t1), Ty::Int(t2)) => match (t1, t2) { |
699 | | (Ty::Str, _) | 695 | (primitive::UncertainIntTy::Unknown, _) |
700 | | (Ty::Never, _) | 696 | | (_, primitive::UncertainIntTy::Unknown) => true, |
701 | | (Ty::Char, _) | 697 | _ => t1 == t2, |
702 | | (Ty::Int(..), Ty::Int(..)) | 698 | }, |
703 | | (Ty::Uint(..), Ty::Uint(..)) | 699 | (Ty::Float(t1), Ty::Float(t2)) => match (t1, t2) { |
704 | | (Ty::Float(..), Ty::Float(..)) => ty1 == ty2, | 700 | (primitive::UncertainFloatTy::Unknown, _) |
701 | | (_, primitive::UncertainFloatTy::Unknown) => true, | ||
702 | _ => t1 == t2, | ||
703 | }, | ||
704 | (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2, | ||
705 | ( | 705 | ( |
706 | Ty::Adt { | 706 | Ty::Adt { |
707 | def_id: def_id1, .. | 707 | def_id: def_id1, .. |
@@ -718,12 +718,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
718 | .iter() | 718 | .iter() |
719 | .zip(ts2.iter()) | 719 | .zip(ts2.iter()) |
720 | .all(|(t1, t2)| self.unify(t1, t2)), | 720 | .all(|(t1, t2)| self.unify(t1, t2)), |
721 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) => { | 721 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) |
722 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | ||
723 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => { | ||
722 | // both type vars are unknown since we tried to resolve them | 724 | // both type vars are unknown since we tried to resolve them |
723 | self.var_unification_table.union(*tv1, *tv2); | 725 | self.var_unification_table.union(*tv1, *tv2); |
724 | true | 726 | true |
725 | } | 727 | } |
726 | (Ty::Infer(InferTy::TypeVar(tv)), other) | (other, Ty::Infer(InferTy::TypeVar(tv))) => { | 728 | (Ty::Infer(InferTy::TypeVar(tv)), other) |
729 | | (other, Ty::Infer(InferTy::TypeVar(tv))) | ||
730 | | (Ty::Infer(InferTy::IntVar(tv)), other) | ||
731 | | (other, Ty::Infer(InferTy::IntVar(tv))) | ||
732 | | (Ty::Infer(InferTy::FloatVar(tv)), other) | ||
733 | | (other, Ty::Infer(InferTy::FloatVar(tv))) => { | ||
727 | // the type var is unknown since we tried to resolve it | 734 | // the type var is unknown since we tried to resolve it |
728 | self.var_unification_table | 735 | self.var_unification_table |
729 | .union_value(*tv, TypeVarValue::Known(other.clone())); | 736 | .union_value(*tv, TypeVarValue::Known(other.clone())); |
@@ -739,10 +746,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
739 | )) | 746 | )) |
740 | } | 747 | } |
741 | 748 | ||
749 | fn new_integer_var(&mut self) -> Ty { | ||
750 | Ty::Infer(InferTy::IntVar( | ||
751 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
752 | )) | ||
753 | } | ||
754 | |||
755 | fn new_float_var(&mut self) -> Ty { | ||
756 | Ty::Infer(InferTy::FloatVar( | ||
757 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
758 | )) | ||
759 | } | ||
760 | |||
742 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | 761 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. |
743 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | 762 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { |
744 | match ty { | 763 | match ty { |
745 | Ty::Unknown => self.new_type_var(), | 764 | Ty::Unknown => self.new_type_var(), |
765 | Ty::Int(primitive::UncertainIntTy::Unknown) => self.new_integer_var(), | ||
766 | Ty::Float(primitive::UncertainFloatTy::Unknown) => self.new_float_var(), | ||
746 | _ => ty, | 767 | _ => ty, |
747 | } | 768 | } |
748 | } | 769 | } |
@@ -757,12 +778,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
757 | /// known type. | 778 | /// known type. |
758 | fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { | 779 | fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { |
759 | ty.fold(&mut |ty| match ty { | 780 | ty.fold(&mut |ty| match ty { |
760 | Ty::Infer(InferTy::TypeVar(tv)) => { | 781 | Ty::Infer(tv) => { |
761 | if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { | 782 | let inner = tv.to_inner(); |
783 | if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() { | ||
762 | // known_ty may contain other variables that are known by now | 784 | // known_ty may contain other variables that are known by now |
763 | self.resolve_ty_as_possible(known_ty.clone()) | 785 | self.resolve_ty_as_possible(known_ty.clone()) |
764 | } else { | 786 | } else { |
765 | Ty::Infer(InferTy::TypeVar(tv)) | 787 | ty |
766 | } | 788 | } |
767 | } | 789 | } |
768 | _ => ty, | 790 | _ => ty, |
@@ -773,8 +795,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
773 | /// otherwise, return ty. | 795 | /// otherwise, return ty. |
774 | fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { | 796 | fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { |
775 | match ty { | 797 | match ty { |
776 | Ty::Infer(InferTy::TypeVar(tv)) => { | 798 | Ty::Infer(tv) => { |
777 | match self.var_unification_table.probe_value(*tv).known() { | 799 | let inner = tv.to_inner(); |
800 | match self.var_unification_table.probe_value(inner).known() { | ||
778 | Some(known_ty) => { | 801 | Some(known_ty) => { |
779 | // The known_ty can't be a type var itself | 802 | // The known_ty can't be a type var itself |
780 | Cow::Owned(known_ty.clone()) | 803 | Cow::Owned(known_ty.clone()) |
@@ -790,61 +813,62 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
790 | /// replaced by Ty::Unknown. | 813 | /// replaced by Ty::Unknown. |
791 | fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { | 814 | fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { |
792 | ty.fold(&mut |ty| match ty { | 815 | ty.fold(&mut |ty| match ty { |
793 | Ty::Infer(InferTy::TypeVar(tv)) => { | 816 | Ty::Infer(tv) => { |
794 | if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { | 817 | let inner = tv.to_inner(); |
818 | if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() { | ||
795 | // known_ty may contain other variables that are known by now | 819 | // known_ty may contain other variables that are known by now |
796 | self.resolve_ty_completely(known_ty.clone()) | 820 | self.resolve_ty_completely(known_ty.clone()) |
797 | } else { | 821 | } else { |
798 | Ty::Unknown | 822 | tv.fallback_value() |
799 | } | 823 | } |
800 | } | 824 | } |
801 | _ => ty, | 825 | _ => ty, |
802 | }) | 826 | }) |
803 | } | 827 | } |
804 | 828 | ||
805 | fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Cancelable<Option<Ty>> { | 829 | fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Option<Ty> { |
806 | if path.is_ident() || path.is_self() { | 830 | if path.is_ident() || path.is_self() { |
807 | // resolve locally | 831 | // resolve locally |
808 | let name = path.as_ident().cloned().unwrap_or_else(Name::self_param); | 832 | let name = path.as_ident().cloned().unwrap_or_else(Name::self_param); |
809 | if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) { | 833 | if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) { |
810 | let ty = ctry!(self.type_of_pat.get(scope_entry.pat())); | 834 | let ty = self.type_of_pat.get(scope_entry.pat())?; |
811 | let ty = self.resolve_ty_as_possible(ty.clone()); | 835 | let ty = self.resolve_ty_as_possible(ty.clone()); |
812 | return Ok(Some(ty)); | 836 | return Some(ty); |
813 | }; | 837 | }; |
814 | }; | 838 | }; |
815 | 839 | ||
816 | // resolve in module | 840 | // resolve in module |
817 | let resolved = ctry!(self.module.resolve_path(self.db, &path)?.take_values()); | 841 | let resolved = self.module.resolve_path(self.db, &path).take_values()?; |
818 | let ty = self.db.type_for_def(resolved)?; | 842 | let ty = self.db.type_for_def(resolved); |
819 | let ty = self.insert_type_vars(ty); | 843 | let ty = self.insert_type_vars(ty); |
820 | Ok(Some(ty)) | 844 | Some(ty) |
821 | } | 845 | } |
822 | 846 | ||
823 | fn resolve_variant(&self, path: Option<&Path>) -> Cancelable<(Ty, Option<DefId>)> { | 847 | fn resolve_variant(&self, path: Option<&Path>) -> (Ty, Option<DefId>) { |
824 | let path = if let Some(path) = path { | 848 | let path = if let Some(path) = path { |
825 | path | 849 | path |
826 | } else { | 850 | } else { |
827 | return Ok((Ty::Unknown, None)); | 851 | return (Ty::Unknown, None); |
828 | }; | 852 | }; |
829 | let def_id = if let Some(def_id) = self.module.resolve_path(self.db, &path)?.take_types() { | 853 | let def_id = if let Some(def_id) = self.module.resolve_path(self.db, &path).take_types() { |
830 | def_id | 854 | def_id |
831 | } else { | 855 | } else { |
832 | return Ok((Ty::Unknown, None)); | 856 | return (Ty::Unknown, None); |
833 | }; | 857 | }; |
834 | Ok(match def_id.resolve(self.db)? { | 858 | match def_id.resolve(self.db) { |
835 | Def::Struct(s) => { | 859 | Def::Struct(s) => { |
836 | let ty = type_for_struct(self.db, s)?; | 860 | let ty = type_for_struct(self.db, s); |
837 | (ty, Some(def_id)) | 861 | (ty, Some(def_id)) |
838 | } | 862 | } |
839 | Def::EnumVariant(ev) => { | 863 | Def::EnumVariant(ev) => { |
840 | let ty = type_for_enum_variant(self.db, ev)?; | 864 | let ty = type_for_enum_variant(self.db, ev); |
841 | (ty, Some(def_id)) | 865 | (ty, Some(def_id)) |
842 | } | 866 | } |
843 | _ => (Ty::Unknown, None), | 867 | _ => (Ty::Unknown, None), |
844 | }) | 868 | } |
845 | } | 869 | } |
846 | 870 | ||
847 | fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Cancelable<Ty> { | 871 | fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Ty { |
848 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 872 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
849 | let ty = match &body[expr] { | 873 | let ty = match &body[expr] { |
850 | Expr::Missing => Ty::Unknown, | 874 | Expr::Missing => Ty::Unknown, |
@@ -854,11 +878,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
854 | else_branch, | 878 | else_branch, |
855 | } => { | 879 | } => { |
856 | // if let is desugared to match, so this is always simple if | 880 | // if let is desugared to match, so this is always simple if |
857 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool))?; | 881 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); |
858 | let then_ty = self.infer_expr(*then_branch, expected)?; | 882 | let then_ty = self.infer_expr(*then_branch, expected); |
859 | match else_branch { | 883 | match else_branch { |
860 | Some(else_branch) => { | 884 | Some(else_branch) => { |
861 | self.infer_expr(*else_branch, expected)?; | 885 | self.infer_expr(*else_branch, expected); |
862 | } | 886 | } |
863 | None => { | 887 | None => { |
864 | // no else branch -> unit | 888 | // no else branch -> unit |
@@ -867,31 +891,31 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
867 | }; | 891 | }; |
868 | then_ty | 892 | then_ty |
869 | } | 893 | } |
870 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected)?, | 894 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), |
871 | Expr::Loop { body } => { | 895 | Expr::Loop { body } => { |
872 | self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; | 896 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
873 | // TODO handle break with value | 897 | // TODO handle break with value |
874 | Ty::Never | 898 | Ty::Never |
875 | } | 899 | } |
876 | Expr::While { condition, body } => { | 900 | Expr::While { condition, body } => { |
877 | // while let is desugared to a match loop, so this is always simple while | 901 | // while let is desugared to a match loop, so this is always simple while |
878 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool))?; | 902 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); |
879 | self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; | 903 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
880 | Ty::unit() | 904 | Ty::unit() |
881 | } | 905 | } |
882 | Expr::For { iterable, body, .. } => { | 906 | Expr::For { iterable, body, .. } => { |
883 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 907 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
884 | // TODO write type for pat | 908 | // TODO write type for pat |
885 | self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; | 909 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
886 | Ty::unit() | 910 | Ty::unit() |
887 | } | 911 | } |
888 | Expr::Lambda { body, .. } => { | 912 | Expr::Lambda { body, .. } => { |
889 | // TODO write types for args, infer lambda type etc. | 913 | // TODO write types for args, infer lambda type etc. |
890 | let _body_ty = self.infer_expr(*body, &Expectation::none())?; | 914 | let _body_ty = self.infer_expr(*body, &Expectation::none()); |
891 | Ty::Unknown | 915 | Ty::Unknown |
892 | } | 916 | } |
893 | Expr::Call { callee, args } => { | 917 | Expr::Call { callee, args } => { |
894 | let callee_ty = self.infer_expr(*callee, &Expectation::none())?; | 918 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); |
895 | let (param_tys, ret_ty) = match &callee_ty { | 919 | let (param_tys, ret_ty) = match &callee_ty { |
896 | Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), | 920 | Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), |
897 | _ => { | 921 | _ => { |
@@ -904,7 +928,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
904 | self.infer_expr( | 928 | self.infer_expr( |
905 | *arg, | 929 | *arg, |
906 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), | 930 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), |
907 | )?; | 931 | ); |
908 | } | 932 | } |
909 | ret_ty | 933 | ret_ty |
910 | } | 934 | } |
@@ -913,12 +937,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
913 | args, | 937 | args, |
914 | method_name, | 938 | method_name, |
915 | } => { | 939 | } => { |
916 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none())?; | 940 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); |
917 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name)?; | 941 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name); |
918 | let method_ty = match resolved { | 942 | let method_ty = match resolved { |
919 | Some(def_id) => { | 943 | Some(def_id) => { |
920 | self.write_method_resolution(expr, def_id); | 944 | self.write_method_resolution(expr, def_id); |
921 | self.db.type_for_def(def_id)? | 945 | self.db.type_for_def(def_id) |
922 | } | 946 | } |
923 | None => Ty::Unknown, | 947 | None => Ty::Unknown, |
924 | }; | 948 | }; |
@@ -940,32 +964,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
940 | self.infer_expr( | 964 | self.infer_expr( |
941 | *arg, | 965 | *arg, |
942 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), | 966 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), |
943 | )?; | 967 | ); |
944 | } | 968 | } |
945 | ret_ty | 969 | ret_ty |
946 | } | 970 | } |
947 | Expr::Match { expr, arms } => { | 971 | Expr::Match { expr, arms } => { |
948 | let _ty = self.infer_expr(*expr, &Expectation::none())?; | 972 | let _ty = self.infer_expr(*expr, &Expectation::none()); |
949 | for arm in arms { | 973 | for arm in arms { |
950 | // TODO type the bindings in pats | 974 | // TODO type the bindings in pats |
951 | // TODO type the guard | 975 | // TODO type the guard |
952 | let _ty = self.infer_expr(arm.expr, &Expectation::none())?; | 976 | let _ty = self.infer_expr(arm.expr, &Expectation::none()); |
953 | } | 977 | } |
954 | // TODO unify all the match arm types | 978 | // TODO unify all the match arm types |
955 | Ty::Unknown | 979 | Ty::Unknown |
956 | } | 980 | } |
957 | Expr::Path(p) => self.infer_path_expr(expr, p)?.unwrap_or(Ty::Unknown), | 981 | Expr::Path(p) => self.infer_path_expr(expr, p).unwrap_or(Ty::Unknown), |
958 | Expr::Continue => Ty::Never, | 982 | Expr::Continue => Ty::Never, |
959 | Expr::Break { expr } => { | 983 | Expr::Break { expr } => { |
960 | if let Some(expr) = expr { | 984 | if let Some(expr) = expr { |
961 | // TODO handle break with value | 985 | // TODO handle break with value |
962 | self.infer_expr(*expr, &Expectation::none())?; | 986 | self.infer_expr(*expr, &Expectation::none()); |
963 | } | 987 | } |
964 | Ty::Never | 988 | Ty::Never |
965 | } | 989 | } |
966 | Expr::Return { expr } => { | 990 | Expr::Return { expr } => { |
967 | if let Some(expr) = expr { | 991 | if let Some(expr) = expr { |
968 | self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone()))?; | 992 | self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone())); |
969 | } | 993 | } |
970 | Ty::Never | 994 | Ty::Never |
971 | } | 995 | } |
@@ -974,62 +998,60 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
974 | fields, | 998 | fields, |
975 | spread, | 999 | spread, |
976 | } => { | 1000 | } => { |
977 | let (ty, def_id) = self.resolve_variant(path.as_ref())?; | 1001 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
978 | for field in fields { | 1002 | for field in fields { |
979 | let field_ty = if let Some(def_id) = def_id { | 1003 | let field_ty = if let Some(def_id) = def_id { |
980 | self.db | 1004 | self.db |
981 | .type_for_field(def_id, field.name.clone())? | 1005 | .type_for_field(def_id, field.name.clone()) |
982 | .unwrap_or(Ty::Unknown) | 1006 | .unwrap_or(Ty::Unknown) |
983 | } else { | 1007 | } else { |
984 | Ty::Unknown | 1008 | Ty::Unknown |
985 | }; | 1009 | }; |
986 | self.infer_expr(field.expr, &Expectation::has_type(field_ty))?; | 1010 | self.infer_expr(field.expr, &Expectation::has_type(field_ty)); |
987 | } | 1011 | } |
988 | if let Some(expr) = spread { | 1012 | if let Some(expr) = spread { |
989 | self.infer_expr(*expr, &Expectation::has_type(ty.clone()))?; | 1013 | self.infer_expr(*expr, &Expectation::has_type(ty.clone())); |
990 | } | 1014 | } |
991 | ty | 1015 | ty |
992 | } | 1016 | } |
993 | Expr::Field { expr, name } => { | 1017 | Expr::Field { expr, name } => { |
994 | let receiver_ty = self.infer_expr(*expr, &Expectation::none())?; | 1018 | let receiver_ty = self.infer_expr(*expr, &Expectation::none()); |
995 | let ty = receiver_ty | 1019 | let ty = receiver_ty |
996 | .autoderef(self.db) | 1020 | .autoderef(self.db) |
997 | .find_map(|derefed_ty| match derefed_ty { | 1021 | .find_map(|derefed_ty| match derefed_ty { |
998 | // this is more complicated than necessary because type_for_field is cancelable | 1022 | // this is more complicated than necessary because type_for_field is cancelable |
999 | Ty::Tuple(fields) => { | 1023 | Ty::Tuple(fields) => { |
1000 | let i = name.to_string().parse::<usize>().ok(); | 1024 | let i = name.to_string().parse::<usize>().ok(); |
1001 | i.and_then(|i| fields.get(i).cloned()).map(Ok) | 1025 | i.and_then(|i| fields.get(i).cloned()) |
1002 | } | ||
1003 | Ty::Adt { def_id, .. } => { | ||
1004 | transpose(self.db.type_for_field(def_id, name.clone())) | ||
1005 | } | 1026 | } |
1027 | Ty::Adt { def_id, .. } => self.db.type_for_field(def_id, name.clone()), | ||
1006 | _ => None, | 1028 | _ => None, |
1007 | }) | 1029 | }) |
1008 | .unwrap_or(Ok(Ty::Unknown))?; | 1030 | .unwrap_or(Ty::Unknown); |
1009 | self.insert_type_vars(ty) | 1031 | self.insert_type_vars(ty) |
1010 | } | 1032 | } |
1011 | Expr::Try { expr } => { | 1033 | Expr::Try { expr } => { |
1012 | let _inner_ty = self.infer_expr(*expr, &Expectation::none())?; | 1034 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1013 | Ty::Unknown | 1035 | Ty::Unknown |
1014 | } | 1036 | } |
1015 | Expr::Cast { expr, type_ref } => { | 1037 | Expr::Cast { expr, type_ref } => { |
1016 | let _inner_ty = self.infer_expr(*expr, &Expectation::none())?; | 1038 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1017 | let cast_ty = | 1039 | let cast_ty = |
1018 | Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref)?; | 1040 | Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref); |
1019 | let cast_ty = self.insert_type_vars(cast_ty); | 1041 | let cast_ty = self.insert_type_vars(cast_ty); |
1020 | // TODO check the cast... | 1042 | // TODO check the cast... |
1021 | cast_ty | 1043 | cast_ty |
1022 | } | 1044 | } |
1023 | Expr::Ref { expr, mutability } => { | 1045 | Expr::Ref { expr, mutability } => { |
1024 | // TODO pass the expectation down | 1046 | // TODO pass the expectation down |
1025 | let inner_ty = self.infer_expr(*expr, &Expectation::none())?; | 1047 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1026 | // TODO reference coercions etc. | 1048 | // TODO reference coercions etc. |
1027 | Ty::Ref(Arc::new(inner_ty), *mutability) | 1049 | Ty::Ref(Arc::new(inner_ty), *mutability) |
1028 | } | 1050 | } |
1029 | Expr::UnaryOp { expr, op } => { | 1051 | Expr::UnaryOp { expr, op } => { |
1030 | let inner_ty = self.infer_expr(*expr, &Expectation::none())?; | 1052 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1031 | match op { | 1053 | match op { |
1032 | Some(UnaryOp::Deref) => { | 1054 | UnaryOp::Deref => { |
1033 | if let Some(derefed_ty) = inner_ty.builtin_deref() { | 1055 | if let Some(derefed_ty) = inner_ty.builtin_deref() { |
1034 | derefed_ty | 1056 | derefed_ty |
1035 | } else { | 1057 | } else { |
@@ -1037,7 +1059,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1037 | Ty::Unknown | 1059 | Ty::Unknown |
1038 | } | 1060 | } |
1039 | } | 1061 | } |
1040 | _ => Ty::Unknown, | 1062 | UnaryOp::Neg => { |
1063 | match inner_ty { | ||
1064 | Ty::Int(primitive::UncertainIntTy::Unknown) | ||
1065 | | Ty::Int(primitive::UncertainIntTy::Signed(..)) | ||
1066 | | Ty::Infer(InferTy::IntVar(..)) | ||
1067 | | Ty::Infer(InferTy::FloatVar(..)) | ||
1068 | | Ty::Float(..) => inner_ty, | ||
1069 | // TODO: resolve ops::Neg trait | ||
1070 | _ => Ty::Unknown, | ||
1071 | } | ||
1072 | } | ||
1073 | UnaryOp::Not if inner_ty == Ty::Bool => Ty::Bool, | ||
1074 | // TODO: resolve ops::Not trait for inner_ty | ||
1075 | UnaryOp::Not => Ty::Unknown, | ||
1041 | } | 1076 | } |
1042 | } | 1077 | } |
1043 | Expr::BinaryOp { lhs, rhs, op } => match op { | 1078 | Expr::BinaryOp { lhs, rhs, op } => match op { |
@@ -1048,11 +1083,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1048 | } | 1083 | } |
1049 | _ => Expectation::none(), | 1084 | _ => Expectation::none(), |
1050 | }; | 1085 | }; |
1051 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation)?; | 1086 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
1052 | // TODO: find implementation of trait corresponding to operation | 1087 | // TODO: find implementation of trait corresponding to operation |
1053 | // symbol and resolve associated `Output` type | 1088 | // symbol and resolve associated `Output` type |
1054 | let rhs_expectation = binary_op_rhs_expectation(*op, lhs_ty); | 1089 | let rhs_expectation = binary_op_rhs_expectation(*op, lhs_ty); |
1055 | let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation))?; | 1090 | let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); |
1056 | 1091 | ||
1057 | // TODO: similar as above, return ty is often associated trait type | 1092 | // TODO: similar as above, return ty is often associated trait type |
1058 | binary_op_return_ty(*op, rhs_ty) | 1093 | binary_op_return_ty(*op, rhs_ty) |
@@ -1062,18 +1097,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1062 | Expr::Tuple { exprs } => { | 1097 | Expr::Tuple { exprs } => { |
1063 | let mut ty_vec = Vec::with_capacity(exprs.len()); | 1098 | let mut ty_vec = Vec::with_capacity(exprs.len()); |
1064 | for arg in exprs.iter() { | 1099 | for arg in exprs.iter() { |
1065 | ty_vec.push(self.infer_expr(*arg, &Expectation::none())?); | 1100 | ty_vec.push(self.infer_expr(*arg, &Expectation::none())); |
1066 | } | 1101 | } |
1067 | 1102 | ||
1068 | Ty::Tuple(Arc::from(ty_vec)) | 1103 | Ty::Tuple(Arc::from(ty_vec)) |
1069 | } | 1104 | } |
1105 | Expr::Literal(lit) => match lit { | ||
1106 | Literal::Bool(..) => Ty::Bool, | ||
1107 | Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared), | ||
1108 | Literal::ByteString(..) => { | ||
1109 | let byte_type = Arc::new(Ty::Int(primitive::UncertainIntTy::Unsigned( | ||
1110 | primitive::UintTy::U8, | ||
1111 | ))); | ||
1112 | let slice_type = Arc::new(Ty::Slice(byte_type)); | ||
1113 | Ty::Ref(slice_type, Mutability::Shared) | ||
1114 | } | ||
1115 | Literal::Char(..) => Ty::Char, | ||
1116 | Literal::Int(_v, ty) => Ty::Int(*ty), | ||
1117 | Literal::Float(_v, ty) => Ty::Float(*ty), | ||
1118 | }, | ||
1070 | }; | 1119 | }; |
1071 | // use a new type variable if we got Ty::Unknown here | 1120 | // use a new type variable if we got Ty::Unknown here |
1072 | let ty = self.insert_type_vars_shallow(ty); | 1121 | let ty = self.insert_type_vars_shallow(ty); |
1073 | self.unify(&ty, &expected.ty); | 1122 | self.unify(&ty, &expected.ty); |
1074 | let ty = self.resolve_ty_as_possible(ty); | 1123 | let ty = self.resolve_ty_as_possible(ty); |
1075 | self.write_expr_ty(expr, ty.clone()); | 1124 | self.write_expr_ty(expr, ty.clone()); |
1076 | Ok(ty) | 1125 | ty |
1077 | } | 1126 | } |
1078 | 1127 | ||
1079 | fn infer_block( | 1128 | fn infer_block( |
@@ -1081,7 +1130,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1081 | statements: &[Statement], | 1130 | statements: &[Statement], |
1082 | tail: Option<ExprId>, | 1131 | tail: Option<ExprId>, |
1083 | expected: &Expectation, | 1132 | expected: &Expectation, |
1084 | ) -> Cancelable<Ty> { | 1133 | ) -> Ty { |
1085 | for stmt in statements { | 1134 | for stmt in statements { |
1086 | match stmt { | 1135 | match stmt { |
1087 | Statement::Let { | 1136 | Statement::Let { |
@@ -1094,10 +1143,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1094 | &self.module, | 1143 | &self.module, |
1095 | self.impl_block.as_ref(), | 1144 | self.impl_block.as_ref(), |
1096 | type_ref.as_ref(), | 1145 | type_ref.as_ref(), |
1097 | )?; | 1146 | ); |
1098 | let decl_ty = self.insert_type_vars(decl_ty); | 1147 | let decl_ty = self.insert_type_vars(decl_ty); |
1099 | let ty = if let Some(expr) = initializer { | 1148 | let ty = if let Some(expr) = initializer { |
1100 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty))?; | 1149 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); |
1101 | expr_ty | 1150 | expr_ty |
1102 | } else { | 1151 | } else { |
1103 | decl_ty | 1152 | decl_ty |
@@ -1106,55 +1155,53 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1106 | self.write_pat_ty(*pat, ty); | 1155 | self.write_pat_ty(*pat, ty); |
1107 | } | 1156 | } |
1108 | Statement::Expr(expr) => { | 1157 | Statement::Expr(expr) => { |
1109 | self.infer_expr(*expr, &Expectation::none())?; | 1158 | self.infer_expr(*expr, &Expectation::none()); |
1110 | } | 1159 | } |
1111 | } | 1160 | } |
1112 | } | 1161 | } |
1113 | let ty = if let Some(expr) = tail { | 1162 | let ty = if let Some(expr) = tail { |
1114 | self.infer_expr(expr, expected)? | 1163 | self.infer_expr(expr, expected) |
1115 | } else { | 1164 | } else { |
1116 | Ty::unit() | 1165 | Ty::unit() |
1117 | }; | 1166 | }; |
1118 | Ok(ty) | 1167 | ty |
1119 | } | 1168 | } |
1120 | 1169 | ||
1121 | fn collect_fn_signature(&mut self, signature: &FnSignature) -> Cancelable<()> { | 1170 | fn collect_fn_signature(&mut self, signature: &FnSignature) { |
1122 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 1171 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
1123 | for (type_ref, pat) in signature.params().iter().zip(body.params()) { | 1172 | for (type_ref, pat) in signature.params().iter().zip(body.params()) { |
1124 | let ty = self.make_ty(type_ref)?; | 1173 | let ty = self.make_ty(type_ref); |
1125 | let ty = self.insert_type_vars(ty); | 1174 | let ty = self.insert_type_vars(ty); |
1126 | self.write_pat_ty(*pat, ty); | 1175 | self.write_pat_ty(*pat, ty); |
1127 | } | 1176 | } |
1128 | self.return_ty = { | 1177 | self.return_ty = { |
1129 | let ty = self.make_ty(signature.ret_type())?; | 1178 | let ty = self.make_ty(signature.ret_type()); |
1130 | let ty = self.insert_type_vars(ty); | 1179 | let ty = self.insert_type_vars(ty); |
1131 | ty | 1180 | ty |
1132 | }; | 1181 | }; |
1133 | Ok(()) | ||
1134 | } | 1182 | } |
1135 | 1183 | ||
1136 | fn infer_body(&mut self) -> Cancelable<()> { | 1184 | fn infer_body(&mut self) { |
1137 | self.infer_expr( | 1185 | self.infer_expr( |
1138 | self.body.body_expr(), | 1186 | self.body.body_expr(), |
1139 | &Expectation::has_type(self.return_ty.clone()), | 1187 | &Expectation::has_type(self.return_ty.clone()), |
1140 | )?; | 1188 | ); |
1141 | Ok(()) | ||
1142 | } | 1189 | } |
1143 | } | 1190 | } |
1144 | 1191 | ||
1145 | pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceResult>> { | 1192 | pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Arc<InferenceResult> { |
1146 | db.check_canceled()?; | 1193 | db.check_canceled(); |
1147 | let function = Function::new(def_id); // TODO: consts also need inference | 1194 | let function = Function::new(def_id); // TODO: consts also need inference |
1148 | let body = function.body(db)?; | 1195 | let body = function.body(db); |
1149 | let scopes = db.fn_scopes(def_id)?; | 1196 | let scopes = db.fn_scopes(def_id); |
1150 | let module = function.module(db)?; | 1197 | let module = function.module(db); |
1151 | let impl_block = function.impl_block(db)?; | 1198 | let impl_block = function.impl_block(db); |
1152 | let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); | 1199 | let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); |
1153 | 1200 | ||
1154 | let signature = function.signature(db); | 1201 | let signature = function.signature(db); |
1155 | ctx.collect_fn_signature(&signature)?; | 1202 | ctx.collect_fn_signature(&signature); |
1156 | 1203 | ||
1157 | ctx.infer_body()?; | 1204 | ctx.infer_body(); |
1158 | 1205 | ||
1159 | Ok(Arc::new(ctx.resolve_all())) | 1206 | Arc::new(ctx.resolve_all()) |
1160 | } | 1207 | } |