diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 557 |
1 files changed, 407 insertions, 150 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 67b523c2c..719b3f7cd 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -1,27 +1,133 @@ | |||
1 | //! The type system. We currently use this to infer types for completion. | ||
2 | //! | ||
3 | //! For type inference, compare the implementations in rustc (the various | ||
4 | //! check_* methods in librustc_typeck/check/mod.rs are a good entry point) and | ||
5 | //! IntelliJ-Rust (org.rust.lang.core.types.infer). Our entry point for | ||
6 | //! inference here is the `infer` function, which infers the types of all | ||
7 | //! expressions in a given function. | ||
8 | //! | ||
9 | //! The central struct here is `Ty`, which represents a type. During inference, | ||
10 | //! it can contain type 'variables' which represent currently unknown types; as | ||
11 | //! we walk through the expressions, we might determine that certain variables | ||
12 | //! need to be equal to each other, or to certain types. To record this, we use | ||
13 | //! the union-find implementation from the `ena` crate, which is extracted from | ||
14 | //! rustc. | ||
15 | |||
1 | mod primitive; | 16 | mod primitive; |
2 | #[cfg(test)] | 17 | #[cfg(test)] |
3 | mod tests; | 18 | mod tests; |
4 | 19 | ||
5 | use std::sync::Arc; | 20 | use std::sync::Arc; |
6 | use std::fmt; | 21 | use std::{fmt, mem}; |
7 | 22 | ||
8 | use log; | 23 | use log; |
9 | use rustc_hash::{FxHashMap}; | 24 | use rustc_hash::FxHashMap; |
25 | use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError}; | ||
10 | 26 | ||
11 | use ra_db::{LocalSyntaxPtr, Cancelable}; | 27 | use ra_db::{LocalSyntaxPtr, Cancelable}; |
12 | use ra_syntax::{ | 28 | use ra_syntax::{ |
13 | SmolStr, | ||
14 | ast::{self, AstNode, LoopBodyOwner, ArgListOwner, PrefixOp}, | 29 | ast::{self, AstNode, LoopBodyOwner, ArgListOwner, PrefixOp}, |
15 | SyntaxNodeRef | 30 | SyntaxNodeRef |
16 | }; | 31 | }; |
17 | 32 | ||
18 | use crate::{ | 33 | use crate::{ |
19 | Def, DefId, FnScopes, Module, Function, Struct, Enum, Path, | 34 | Def, DefId, FnScopes, Module, Function, Struct, Enum, Path, Name, AsName, |
20 | db::HirDatabase, | 35 | db::HirDatabase, |
21 | adt::VariantData, | ||
22 | type_ref::{TypeRef, Mutability}, | 36 | type_ref::{TypeRef, Mutability}, |
23 | }; | 37 | }; |
24 | 38 | ||
39 | /// The ID of a type variable. | ||
40 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | ||
41 | pub struct TypeVarId(u32); | ||
42 | |||
43 | impl UnifyKey for TypeVarId { | ||
44 | type Value = TypeVarValue; | ||
45 | |||
46 | fn index(&self) -> u32 { | ||
47 | self.0 | ||
48 | } | ||
49 | |||
50 | fn from_index(i: u32) -> Self { | ||
51 | TypeVarId(i) | ||
52 | } | ||
53 | |||
54 | fn tag() -> &'static str { | ||
55 | "TypeVarId" | ||
56 | } | ||
57 | } | ||
58 | |||
59 | /// The value of a type variable: either we already know the type, or we don't | ||
60 | /// know it yet. | ||
61 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
62 | pub enum TypeVarValue { | ||
63 | Known(Ty), | ||
64 | Unknown, | ||
65 | } | ||
66 | |||
67 | impl TypeVarValue { | ||
68 | fn known(&self) -> Option<&Ty> { | ||
69 | match self { | ||
70 | TypeVarValue::Known(ty) => Some(ty), | ||
71 | TypeVarValue::Unknown => None, | ||
72 | } | ||
73 | } | ||
74 | } | ||
75 | |||
76 | impl UnifyValue for TypeVarValue { | ||
77 | type Error = NoError; | ||
78 | |||
79 | fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> { | ||
80 | match (value1, value2) { | ||
81 | // We should never equate two type variables, both of which have | ||
82 | // known types. Instead, we recursively equate those types. | ||
83 | (TypeVarValue::Known(..), TypeVarValue::Known(..)) => { | ||
84 | panic!("equating two type variables, both of which have known types") | ||
85 | } | ||
86 | |||
87 | // If one side is known, prefer that one. | ||
88 | (TypeVarValue::Known(..), TypeVarValue::Unknown) => Ok(value1.clone()), | ||
89 | (TypeVarValue::Unknown, TypeVarValue::Known(..)) => Ok(value2.clone()), | ||
90 | |||
91 | (TypeVarValue::Unknown, TypeVarValue::Unknown) => Ok(TypeVarValue::Unknown), | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 | /// The kinds of placeholders we need during type inference. Currently, we only | ||
97 | /// have type variables; in the future, we will probably also need int and float | ||
98 | /// variables, for inference of literal values (e.g. `100` could be one of | ||
99 | /// several integer types). | ||
100 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | ||
101 | pub enum InferTy { | ||
102 | TypeVar(TypeVarId), | ||
103 | } | ||
104 | |||
105 | /// When inferring an expression, we propagate downward whatever type hint we | ||
106 | /// are able in the form of an `Expectation`. | ||
107 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
108 | struct Expectation { | ||
109 | ty: Ty, | ||
110 | // TODO: In some cases, we need to be aware whether the expectation is that | ||
111 | // the type match exactly what we passed, or whether it just needs to be | ||
112 | // coercible to the expected type. See Expectation::rvalue_hint in rustc. | ||
113 | } | ||
114 | |||
115 | impl Expectation { | ||
116 | /// The expectation that the type of the expression needs to equal the given | ||
117 | /// type. | ||
118 | fn has_type(ty: Ty) -> Self { | ||
119 | Expectation { ty } | ||
120 | } | ||
121 | |||
122 | /// This expresses no expectation on the type. | ||
123 | fn none() -> Self { | ||
124 | Expectation { ty: Ty::Unknown } | ||
125 | } | ||
126 | } | ||
127 | |||
128 | /// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs). | ||
129 | /// | ||
130 | /// This should be cheap to clone. | ||
25 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 131 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] |
26 | pub enum Ty { | 132 | pub enum Ty { |
27 | /// The primitive boolean type. Written as `bool`. | 133 | /// The primitive boolean type. Written as `bool`. |
@@ -45,7 +151,7 @@ pub enum Ty { | |||
45 | /// The DefId of the struct/enum. | 151 | /// The DefId of the struct/enum. |
46 | def_id: DefId, | 152 | def_id: DefId, |
47 | /// The name, for displaying. | 153 | /// The name, for displaying. |
48 | name: SmolStr, | 154 | name: Name, |
49 | // later we'll need generic substitutions here | 155 | // later we'll need generic substitutions here |
50 | }, | 156 | }, |
51 | 157 | ||
@@ -55,14 +161,14 @@ pub enum Ty { | |||
55 | // An array with the given length. Written as `[T; n]`. | 161 | // An array with the given length. Written as `[T; n]`. |
56 | // Array(Ty, ty::Const), | 162 | // Array(Ty, ty::Const), |
57 | /// The pointee of an array slice. Written as `[T]`. | 163 | /// The pointee of an array slice. Written as `[T]`. |
58 | Slice(TyRef), | 164 | Slice(Arc<Ty>), |
59 | 165 | ||
60 | /// A raw pointer. Written as `*mut T` or `*const T` | 166 | /// A raw pointer. Written as `*mut T` or `*const T` |
61 | RawPtr(TyRef, Mutability), | 167 | RawPtr(Arc<Ty>, Mutability), |
62 | 168 | ||
63 | /// A reference; a pointer with an associated lifetime. Written as | 169 | /// A reference; a pointer with an associated lifetime. Written as |
64 | /// `&'a mut T` or `&'a T`. | 170 | /// `&'a mut T` or `&'a T`. |
65 | Ref(TyRef, Mutability), | 171 | Ref(Arc<Ty>, Mutability), |
66 | 172 | ||
67 | /// A pointer to a function. Written as `fn() -> i32`. | 173 | /// A pointer to a function. Written as `fn() -> i32`. |
68 | /// | 174 | /// |
@@ -74,52 +180,51 @@ pub enum Ty { | |||
74 | /// ``` | 180 | /// ``` |
75 | FnPtr(Arc<FnSig>), | 181 | FnPtr(Arc<FnSig>), |
76 | 182 | ||
183 | // rustc has a separate type for each function, which just coerces to the | ||
184 | // above function pointer type. Once we implement generics, we will probably | ||
185 | // need this as well. | ||
186 | |||
77 | // A trait, defined with `dyn trait`. | 187 | // A trait, defined with `dyn trait`. |
78 | // Dynamic(), | 188 | // Dynamic(), |
79 | /// The anonymous type of a closure. Used to represent the type of | 189 | // The anonymous type of a closure. Used to represent the type of |
80 | /// `|a| a`. | 190 | // `|a| a`. |
81 | // Closure(DefId, ClosureSubsts<'tcx>), | 191 | // Closure(DefId, ClosureSubsts<'tcx>), |
82 | 192 | ||
83 | /// The anonymous type of a generator. Used to represent the type of | 193 | // The anonymous type of a generator. Used to represent the type of |
84 | /// `|a| yield a`. | 194 | // `|a| yield a`. |
85 | // Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability), | 195 | // Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability), |
86 | 196 | ||
87 | /// A type representin the types stored inside a generator. | 197 | // A type representin the types stored inside a generator. |
88 | /// This should only appear in GeneratorInteriors. | 198 | // This should only appear in GeneratorInteriors. |
89 | // GeneratorWitness(Binder<&'tcx List<Ty<'tcx>>>), | 199 | // GeneratorWitness(Binder<&'tcx List<Ty<'tcx>>>), |
90 | 200 | /// The never type `!`. | |
91 | /// The never type `!` | ||
92 | Never, | 201 | Never, |
93 | 202 | ||
94 | /// A tuple type. For example, `(i32, bool)`. | 203 | /// A tuple type. For example, `(i32, bool)`. |
95 | Tuple(Vec<Ty>), | 204 | Tuple(Arc<[Ty]>), |
96 | 205 | ||
97 | // The projection of an associated type. For example, | 206 | // The projection of an associated type. For example, |
98 | // `<T as Trait<..>>::N`. | 207 | // `<T as Trait<..>>::N`.pub |
99 | // Projection(ProjectionTy), | 208 | // Projection(ProjectionTy), |
100 | 209 | ||
101 | // Opaque (`impl Trait`) type found in a return type. | 210 | // Opaque (`impl Trait`) type found in a return type. |
102 | // The `DefId` comes either from | ||
103 | // * the `impl Trait` ast::Ty node, | ||
104 | // * or the `existential type` declaration | ||
105 | // The substitutions are for the generics of the function in question. | ||
106 | // Opaque(DefId, Substs), | 211 | // Opaque(DefId, Substs), |
107 | 212 | ||
108 | // A type parameter; for example, `T` in `fn f<T>(x: T) {} | 213 | // A type parameter; for example, `T` in `fn f<T>(x: T) {} |
109 | // Param(ParamTy), | 214 | // Param(ParamTy), |
110 | 215 | /// A type variable used during type checking. Not to be confused with a | |
111 | // A placeholder type - universally quantified higher-ranked type. | 216 | /// type parameter. |
112 | // Placeholder(ty::PlaceholderType), | 217 | Infer(InferTy), |
113 | 218 | ||
114 | // A type variable used during type checking. | 219 | /// A placeholder for a type which could not be computed; this is propagated |
115 | // Infer(InferTy), | 220 | /// to avoid useless error messages. Doubles as a placeholder where type |
116 | /// A placeholder for a type which could not be computed; this is | 221 | /// variables are inserted before type checking, since we want to try to |
117 | /// propagated to avoid useless error messages. | 222 | /// infer a better type here anyway -- for the IDE use case, we want to try |
223 | /// to infer as much as possible even in the presence of type errors. | ||
118 | Unknown, | 224 | Unknown, |
119 | } | 225 | } |
120 | 226 | ||
121 | type TyRef = Arc<Ty>; | 227 | /// A function signature. |
122 | |||
123 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 228 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] |
124 | pub struct FnSig { | 229 | pub struct FnSig { |
125 | input: Vec<Ty>, | 230 | input: Vec<Ty>, |
@@ -138,8 +243,8 @@ impl Ty { | |||
138 | let inner_tys = inner | 243 | let inner_tys = inner |
139 | .iter() | 244 | .iter() |
140 | .map(|tr| Ty::from_hir(db, module, tr)) | 245 | .map(|tr| Ty::from_hir(db, module, tr)) |
141 | .collect::<Cancelable<_>>()?; | 246 | .collect::<Cancelable<Vec<_>>>()?; |
142 | Ty::Tuple(inner_tys) | 247 | Ty::Tuple(inner_tys.into()) |
143 | } | 248 | } |
144 | TypeRef::Path(path) => Ty::from_hir_path(db, module, path)?, | 249 | TypeRef::Path(path) => Ty::from_hir_path(db, module, path)?, |
145 | TypeRef::RawPtr(inner, mutability) => { | 250 | TypeRef::RawPtr(inner, mutability) => { |
@@ -155,7 +260,7 @@ impl Ty { | |||
155 | let inner_ty = Ty::from_hir(db, module, inner)?; | 260 | let inner_ty = Ty::from_hir(db, module, inner)?; |
156 | Ty::Ref(Arc::new(inner_ty), *mutability) | 261 | Ty::Ref(Arc::new(inner_ty), *mutability) |
157 | } | 262 | } |
158 | TypeRef::Placeholder => Ty::Unknown, // TODO | 263 | TypeRef::Placeholder => Ty::Unknown, |
159 | TypeRef::Fn(params) => { | 264 | TypeRef::Fn(params) => { |
160 | let mut inner_tys = params | 265 | let mut inner_tys = params |
161 | .iter() | 266 | .iter() |
@@ -179,13 +284,12 @@ impl Ty { | |||
179 | module: &Module, | 284 | module: &Module, |
180 | path: &Path, | 285 | path: &Path, |
181 | ) -> Cancelable<Self> { | 286 | ) -> Cancelable<Self> { |
182 | if path.is_ident() { | 287 | if let Some(name) = path.as_ident() { |
183 | let name = &path.segments[0]; | 288 | if let Some(int_ty) = primitive::IntTy::from_name(name) { |
184 | if let Some(int_ty) = primitive::IntTy::from_string(&name) { | ||
185 | return Ok(Ty::Int(int_ty)); | 289 | return Ok(Ty::Int(int_ty)); |
186 | } else if let Some(uint_ty) = primitive::UintTy::from_string(&name) { | 290 | } else if let Some(uint_ty) = primitive::UintTy::from_name(name) { |
187 | return Ok(Ty::Uint(uint_ty)); | 291 | return Ok(Ty::Uint(uint_ty)); |
188 | } else if let Some(float_ty) = primitive::FloatTy::from_string(&name) { | 292 | } else if let Some(float_ty) = primitive::FloatTy::from_name(name) { |
189 | return Ok(Ty::Float(float_ty)); | 293 | return Ok(Ty::Float(float_ty)); |
190 | } | 294 | } |
191 | } | 295 | } |
@@ -219,7 +323,41 @@ impl Ty { | |||
219 | } | 323 | } |
220 | 324 | ||
221 | pub fn unit() -> Self { | 325 | pub fn unit() -> Self { |
222 | Ty::Tuple(Vec::new()) | 326 | Ty::Tuple(Arc::new([])) |
327 | } | ||
328 | |||
329 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | ||
330 | f(self); | ||
331 | match self { | ||
332 | Ty::Slice(t) => Arc::make_mut(t).walk_mut(f), | ||
333 | Ty::RawPtr(t, _) => Arc::make_mut(t).walk_mut(f), | ||
334 | Ty::Ref(t, _) => Arc::make_mut(t).walk_mut(f), | ||
335 | Ty::Tuple(ts) => { | ||
336 | // Without an Arc::make_mut_slice, we can't avoid the clone here: | ||
337 | let mut v: Vec<_> = ts.iter().cloned().collect(); | ||
338 | for t in &mut v { | ||
339 | t.walk_mut(f); | ||
340 | } | ||
341 | *ts = v.into(); | ||
342 | } | ||
343 | Ty::FnPtr(sig) => { | ||
344 | let sig_mut = Arc::make_mut(sig); | ||
345 | for input in &mut sig_mut.input { | ||
346 | input.walk_mut(f); | ||
347 | } | ||
348 | sig_mut.output.walk_mut(f); | ||
349 | } | ||
350 | Ty::Adt { .. } => {} // need to walk type parameters later | ||
351 | _ => {} | ||
352 | } | ||
353 | } | ||
354 | |||
355 | fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Ty { | ||
356 | self.walk_mut(&mut |ty_mut| { | ||
357 | let ty = mem::replace(ty_mut, Ty::Unknown); | ||
358 | *ty_mut = f(ty); | ||
359 | }); | ||
360 | self | ||
223 | } | 361 | } |
224 | } | 362 | } |
225 | 363 | ||
@@ -238,7 +376,7 @@ impl fmt::Display for Ty { | |||
238 | Ty::Never => write!(f, "!"), | 376 | Ty::Never => write!(f, "!"), |
239 | Ty::Tuple(ts) => { | 377 | Ty::Tuple(ts) => { |
240 | write!(f, "(")?; | 378 | write!(f, "(")?; |
241 | for t in ts { | 379 | for t in ts.iter() { |
242 | write!(f, "{},", t)?; | 380 | write!(f, "{},", t)?; |
243 | } | 381 | } |
244 | write!(f, ")") | 382 | write!(f, ")") |
@@ -252,11 +390,16 @@ impl fmt::Display for Ty { | |||
252 | } | 390 | } |
253 | Ty::Adt { name, .. } => write!(f, "{}", name), | 391 | Ty::Adt { name, .. } => write!(f, "{}", name), |
254 | Ty::Unknown => write!(f, "[unknown]"), | 392 | Ty::Unknown => write!(f, "[unknown]"), |
393 | Ty::Infer(..) => write!(f, "_"), | ||
255 | } | 394 | } |
256 | } | 395 | } |
257 | } | 396 | } |
258 | 397 | ||
259 | pub fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> { | 398 | // Functions returning declared types for items |
399 | |||
400 | /// Compute the declared type of a function. This should not need to look at the | ||
401 | /// function body (but currently uses the function AST, so does anyway - TODO). | ||
402 | fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> { | ||
260 | let syntax = f.syntax(db); | 403 | let syntax = f.syntax(db); |
261 | let module = f.module(db)?; | 404 | let module = f.module(db)?; |
262 | let node = syntax.borrowed(); | 405 | let node = syntax.borrowed(); |
@@ -269,30 +412,30 @@ pub fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> { | |||
269 | .collect() | 412 | .collect() |
270 | }) | 413 | }) |
271 | .unwrap_or_else(|| Ok(Vec::new()))?; | 414 | .unwrap_or_else(|| Ok(Vec::new()))?; |
272 | let output = Ty::from_ast_opt(db, &module, node.ret_type().and_then(|rt| rt.type_ref()))?; | 415 | let output = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) { |
416 | Ty::from_ast(db, &module, type_ref)? | ||
417 | } else { | ||
418 | Ty::unit() | ||
419 | }; | ||
273 | let sig = FnSig { input, output }; | 420 | let sig = FnSig { input, output }; |
274 | Ok(Ty::FnPtr(Arc::new(sig))) | 421 | Ok(Ty::FnPtr(Arc::new(sig))) |
275 | } | 422 | } |
276 | 423 | ||
277 | pub fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Cancelable<Ty> { | 424 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Cancelable<Ty> { |
278 | Ok(Ty::Adt { | 425 | Ok(Ty::Adt { |
279 | def_id: s.def_id(), | 426 | def_id: s.def_id(), |
280 | name: s | 427 | name: s.name(db)?.unwrap_or_else(Name::missing), |
281 | .name(db)? | ||
282 | .unwrap_or_else(|| SmolStr::new("[unnamed struct]")), | ||
283 | }) | 428 | }) |
284 | } | 429 | } |
285 | 430 | ||
286 | pub fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Cancelable<Ty> { | 431 | pub fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Cancelable<Ty> { |
287 | Ok(Ty::Adt { | 432 | Ok(Ty::Adt { |
288 | def_id: s.def_id(), | 433 | def_id: s.def_id(), |
289 | name: s | 434 | name: s.name(db)?.unwrap_or_else(Name::missing), |
290 | .name(db)? | ||
291 | .unwrap_or_else(|| SmolStr::new("[unnamed enum]")), | ||
292 | }) | 435 | }) |
293 | } | 436 | } |
294 | 437 | ||
295 | pub fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ty> { | 438 | pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ty> { |
296 | let def = def_id.resolve(db)?; | 439 | let def = def_id.resolve(db)?; |
297 | match def { | 440 | match def { |
298 | Def::Module(..) => { | 441 | Def::Module(..) => { |
@@ -309,11 +452,7 @@ pub fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ty> { | |||
309 | } | 452 | } |
310 | } | 453 | } |
311 | 454 | ||
312 | pub(super) fn type_for_field( | 455 | pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Cancelable<Ty> { |
313 | db: &impl HirDatabase, | ||
314 | def_id: DefId, | ||
315 | field: SmolStr, | ||
316 | ) -> Cancelable<Ty> { | ||
317 | let def = def_id.resolve(db)?; | 456 | let def = def_id.resolve(db)?; |
318 | let variant_data = match def { | 457 | let variant_data = match def { |
319 | Def::Struct(s) => { | 458 | Def::Struct(s) => { |
@@ -336,23 +475,29 @@ pub(super) fn type_for_field( | |||
336 | Ty::from_hir(db, &module, &type_ref) | 475 | Ty::from_hir(db, &module, &type_ref) |
337 | } | 476 | } |
338 | 477 | ||
478 | /// The result of type inference: A mapping from expressions and patterns to types. | ||
339 | #[derive(Clone, PartialEq, Eq, Debug)] | 479 | #[derive(Clone, PartialEq, Eq, Debug)] |
340 | pub struct InferenceResult { | 480 | pub struct InferenceResult { |
341 | type_of: FxHashMap<LocalSyntaxPtr, Ty>, | 481 | type_of: FxHashMap<LocalSyntaxPtr, Ty>, |
342 | } | 482 | } |
343 | 483 | ||
344 | impl InferenceResult { | 484 | impl InferenceResult { |
485 | /// Returns the type of the given syntax node, if it was inferred. Will | ||
486 | /// return `None` for syntax nodes not in the inferred function or not | ||
487 | /// pointing to an expression/pattern, `Some(Ty::Unknown)` for | ||
488 | /// expressions/patterns that could not be inferred. | ||
345 | pub fn type_of_node(&self, node: SyntaxNodeRef) -> Option<Ty> { | 489 | pub fn type_of_node(&self, node: SyntaxNodeRef) -> Option<Ty> { |
346 | self.type_of.get(&LocalSyntaxPtr::new(node)).cloned() | 490 | self.type_of.get(&LocalSyntaxPtr::new(node)).cloned() |
347 | } | 491 | } |
348 | } | 492 | } |
349 | 493 | ||
494 | /// The inference context contains all information needed during type inference. | ||
350 | #[derive(Clone, Debug)] | 495 | #[derive(Clone, Debug)] |
351 | pub struct InferenceContext<'a, D: HirDatabase> { | 496 | struct InferenceContext<'a, D: HirDatabase> { |
352 | db: &'a D, | 497 | db: &'a D, |
353 | scopes: Arc<FnScopes>, | 498 | scopes: Arc<FnScopes>, |
354 | module: Module, | 499 | module: Module, |
355 | // TODO unification tables... | 500 | var_unification_table: InPlaceUnificationTable<TypeVarId>, |
356 | type_of: FxHashMap<LocalSyntaxPtr, Ty>, | 501 | type_of: FxHashMap<LocalSyntaxPtr, Ty>, |
357 | } | 502 | } |
358 | 503 | ||
@@ -360,33 +505,116 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
360 | fn new(db: &'a D, scopes: Arc<FnScopes>, module: Module) -> Self { | 505 | fn new(db: &'a D, scopes: Arc<FnScopes>, module: Module) -> Self { |
361 | InferenceContext { | 506 | InferenceContext { |
362 | type_of: FxHashMap::default(), | 507 | type_of: FxHashMap::default(), |
508 | var_unification_table: InPlaceUnificationTable::new(), | ||
363 | db, | 509 | db, |
364 | scopes, | 510 | scopes, |
365 | module, | 511 | module, |
366 | } | 512 | } |
367 | } | 513 | } |
368 | 514 | ||
515 | fn resolve_all(mut self) -> InferenceResult { | ||
516 | let mut types = mem::replace(&mut self.type_of, FxHashMap::default()); | ||
517 | for ty in types.values_mut() { | ||
518 | let resolved = self.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); | ||
519 | *ty = resolved; | ||
520 | } | ||
521 | InferenceResult { type_of: types } | ||
522 | } | ||
523 | |||
369 | fn write_ty(&mut self, node: SyntaxNodeRef, ty: Ty) { | 524 | fn write_ty(&mut self, node: SyntaxNodeRef, ty: Ty) { |
370 | self.type_of.insert(LocalSyntaxPtr::new(node), ty); | 525 | self.type_of.insert(LocalSyntaxPtr::new(node), ty); |
371 | } | 526 | } |
372 | 527 | ||
373 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> Option<Ty> { | 528 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { |
374 | if *ty1 == Ty::Unknown { | 529 | match (ty1, ty2) { |
375 | return Some(ty2.clone()); | 530 | (Ty::Unknown, ..) => true, |
376 | } | 531 | (.., Ty::Unknown) => true, |
377 | if *ty2 == Ty::Unknown { | 532 | (Ty::Bool, _) |
378 | return Some(ty1.clone()); | 533 | | (Ty::Str, _) |
534 | | (Ty::Never, _) | ||
535 | | (Ty::Char, _) | ||
536 | | (Ty::Int(..), Ty::Int(..)) | ||
537 | | (Ty::Uint(..), Ty::Uint(..)) | ||
538 | | (Ty::Float(..), Ty::Float(..)) => ty1 == ty2, | ||
539 | ( | ||
540 | Ty::Adt { | ||
541 | def_id: def_id1, .. | ||
542 | }, | ||
543 | Ty::Adt { | ||
544 | def_id: def_id2, .. | ||
545 | }, | ||
546 | ) if def_id1 == def_id2 => true, | ||
547 | (Ty::Slice(t1), Ty::Slice(t2)) => self.unify(t1, t2), | ||
548 | (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => self.unify(t1, t2), | ||
549 | (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify(t1, t2), | ||
550 | (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, | ||
551 | (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => ts1 | ||
552 | .iter() | ||
553 | .zip(ts2.iter()) | ||
554 | .all(|(t1, t2)| self.unify(t1, t2)), | ||
555 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) => { | ||
556 | self.var_unification_table.union(*tv1, *tv2); | ||
557 | true | ||
558 | } | ||
559 | (Ty::Infer(InferTy::TypeVar(tv)), other) | (other, Ty::Infer(InferTy::TypeVar(tv))) => { | ||
560 | self.var_unification_table | ||
561 | .union_value(*tv, TypeVarValue::Known(other.clone())); | ||
562 | true | ||
563 | } | ||
564 | _ => false, | ||
379 | } | 565 | } |
380 | if ty1 == ty2 { | 566 | } |
381 | return Some(ty1.clone()); | 567 | |
568 | fn new_type_var(&mut self) -> Ty { | ||
569 | Ty::Infer(InferTy::TypeVar( | ||
570 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
571 | )) | ||
572 | } | ||
573 | |||
574 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | ||
575 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | ||
576 | match ty { | ||
577 | Ty::Unknown => self.new_type_var(), | ||
578 | _ => ty, | ||
382 | } | 579 | } |
383 | // TODO implement actual unification | ||
384 | return None; | ||
385 | } | 580 | } |
386 | 581 | ||
387 | fn unify_with_coercion(&mut self, ty1: &Ty, ty2: &Ty) -> Option<Ty> { | 582 | fn insert_type_vars(&mut self, ty: Ty) -> Ty { |
388 | // TODO implement coercion | 583 | ty.fold(&mut |ty| self.insert_type_vars_shallow(ty)) |
389 | self.unify(ty1, ty2) | 584 | } |
585 | |||
586 | /// Resolves the type as far as currently possible, replacing type variables | ||
587 | /// by their known types. All types returned by the infer_* functions should | ||
588 | /// be resolved as far as possible, i.e. contain no type variables with | ||
589 | /// known type. | ||
590 | fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { | ||
591 | ty.fold(&mut |ty| match ty { | ||
592 | Ty::Infer(InferTy::TypeVar(tv)) => { | ||
593 | if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { | ||
594 | // known_ty may contain other variables that are known by now | ||
595 | self.resolve_ty_as_possible(known_ty.clone()) | ||
596 | } else { | ||
597 | Ty::Infer(InferTy::TypeVar(tv)) | ||
598 | } | ||
599 | } | ||
600 | _ => ty, | ||
601 | }) | ||
602 | } | ||
603 | |||
604 | /// Resolves the type completely; type variables without known type are | ||
605 | /// replaced by Ty::Unknown. | ||
606 | fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { | ||
607 | ty.fold(&mut |ty| match ty { | ||
608 | Ty::Infer(InferTy::TypeVar(tv)) => { | ||
609 | if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { | ||
610 | // known_ty may contain other variables that are known by now | ||
611 | self.resolve_ty_completely(known_ty.clone()) | ||
612 | } else { | ||
613 | Ty::Unknown | ||
614 | } | ||
615 | } | ||
616 | _ => ty, | ||
617 | }) | ||
390 | } | 618 | } |
391 | 619 | ||
392 | fn infer_path_expr(&mut self, expr: ast::PathExpr) -> Cancelable<Option<Ty>> { | 620 | fn infer_path_expr(&mut self, expr: ast::PathExpr) -> Cancelable<Option<Ty>> { |
@@ -397,21 +625,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
397 | let name = ctry!(ast_path.segment().and_then(|s| s.name_ref())); | 625 | let name = ctry!(ast_path.segment().and_then(|s| s.name_ref())); |
398 | if let Some(scope_entry) = self.scopes.resolve_local_name(name) { | 626 | if let Some(scope_entry) = self.scopes.resolve_local_name(name) { |
399 | let ty = ctry!(self.type_of.get(&scope_entry.ptr())); | 627 | let ty = ctry!(self.type_of.get(&scope_entry.ptr())); |
400 | return Ok(Some(ty.clone())); | 628 | let ty = self.resolve_ty_as_possible(ty.clone()); |
629 | return Ok(Some(ty)); | ||
401 | }; | 630 | }; |
402 | }; | 631 | }; |
403 | 632 | ||
404 | // resolve in module | 633 | // resolve in module |
405 | let resolved = ctry!(self.module.resolve_path(self.db, &path)?.take_values()); | 634 | let resolved = ctry!(self.module.resolve_path(self.db, &path)?.take_values()); |
406 | let ty = self.db.type_for_def(resolved)?; | 635 | let ty = self.db.type_for_def(resolved)?; |
407 | // TODO we will need to add type variables for type parameters etc. here | 636 | let ty = self.insert_type_vars(ty); |
408 | Ok(Some(ty)) | 637 | Ok(Some(ty)) |
409 | } | 638 | } |
410 | 639 | ||
411 | fn resolve_variant( | 640 | fn resolve_variant(&self, path: Option<ast::Path>) -> Cancelable<(Ty, Option<DefId>)> { |
412 | &self, | ||
413 | path: Option<ast::Path>, | ||
414 | ) -> Cancelable<(Ty, Option<Arc<VariantData>>)> { | ||
415 | let path = if let Some(path) = path.and_then(Path::from_ast) { | 641 | let path = if let Some(path) = path.and_then(Path::from_ast) { |
416 | path | 642 | path |
417 | } else { | 643 | } else { |
@@ -424,102 +650,116 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
424 | }; | 650 | }; |
425 | Ok(match def_id.resolve(self.db)? { | 651 | Ok(match def_id.resolve(self.db)? { |
426 | Def::Struct(s) => { | 652 | Def::Struct(s) => { |
427 | let struct_data = self.db.struct_data(def_id)?; | ||
428 | let ty = type_for_struct(self.db, s)?; | 653 | let ty = type_for_struct(self.db, s)?; |
429 | (ty, Some(struct_data.variant_data().clone())) | 654 | (ty, Some(def_id)) |
430 | } | 655 | } |
431 | _ => (Ty::Unknown, None), | 656 | _ => (Ty::Unknown, None), |
432 | }) | 657 | }) |
433 | } | 658 | } |
434 | 659 | ||
435 | fn infer_expr_opt(&mut self, expr: Option<ast::Expr>) -> Cancelable<Ty> { | 660 | fn infer_expr_opt( |
661 | &mut self, | ||
662 | expr: Option<ast::Expr>, | ||
663 | expected: &Expectation, | ||
664 | ) -> Cancelable<Ty> { | ||
436 | if let Some(e) = expr { | 665 | if let Some(e) = expr { |
437 | self.infer_expr(e) | 666 | self.infer_expr(e, expected) |
438 | } else { | 667 | } else { |
439 | Ok(Ty::Unknown) | 668 | Ok(Ty::Unknown) |
440 | } | 669 | } |
441 | } | 670 | } |
442 | 671 | ||
443 | fn infer_expr(&mut self, expr: ast::Expr) -> Cancelable<Ty> { | 672 | fn infer_expr(&mut self, expr: ast::Expr, expected: &Expectation) -> Cancelable<Ty> { |
444 | let ty = match expr { | 673 | let ty = match expr { |
445 | ast::Expr::IfExpr(e) => { | 674 | ast::Expr::IfExpr(e) => { |
446 | if let Some(condition) = e.condition() { | 675 | if let Some(condition) = e.condition() { |
447 | // TODO if no pat, this should be bool | 676 | let expected = if condition.pat().is_none() { |
448 | self.infer_expr_opt(condition.expr())?; | 677 | Expectation::has_type(Ty::Bool) |
678 | } else { | ||
679 | Expectation::none() | ||
680 | }; | ||
681 | self.infer_expr_opt(condition.expr(), &expected)?; | ||
449 | // TODO write type for pat | 682 | // TODO write type for pat |
450 | }; | 683 | }; |
451 | let if_ty = self.infer_block_opt(e.then_branch())?; | 684 | let if_ty = self.infer_block_opt(e.then_branch(), expected)?; |
452 | let else_ty = self.infer_block_opt(e.else_branch())?; | 685 | if let Some(else_branch) = e.else_branch() { |
453 | if let Some(ty) = self.unify(&if_ty, &else_ty) { | 686 | self.infer_block(else_branch, expected)?; |
454 | ty | ||
455 | } else { | 687 | } else { |
456 | // TODO report diagnostic | 688 | // no else branch -> unit |
457 | Ty::Unknown | 689 | self.unify(&expected.ty, &Ty::unit()); // actually coerce |
458 | } | 690 | } |
691 | if_ty | ||
459 | } | 692 | } |
460 | ast::Expr::BlockExpr(e) => self.infer_block_opt(e.block())?, | 693 | ast::Expr::BlockExpr(e) => self.infer_block_opt(e.block(), expected)?, |
461 | ast::Expr::LoopExpr(e) => { | 694 | ast::Expr::LoopExpr(e) => { |
462 | self.infer_block_opt(e.loop_body())?; | 695 | self.infer_block_opt(e.loop_body(), &Expectation::has_type(Ty::unit()))?; |
463 | // TODO never, or the type of the break param | 696 | // TODO never, or the type of the break param |
464 | Ty::Unknown | 697 | Ty::Unknown |
465 | } | 698 | } |
466 | ast::Expr::WhileExpr(e) => { | 699 | ast::Expr::WhileExpr(e) => { |
467 | if let Some(condition) = e.condition() { | 700 | if let Some(condition) = e.condition() { |
468 | // TODO if no pat, this should be bool | 701 | let expected = if condition.pat().is_none() { |
469 | self.infer_expr_opt(condition.expr())?; | 702 | Expectation::has_type(Ty::Bool) |
703 | } else { | ||
704 | Expectation::none() | ||
705 | }; | ||
706 | self.infer_expr_opt(condition.expr(), &expected)?; | ||
470 | // TODO write type for pat | 707 | // TODO write type for pat |
471 | }; | 708 | }; |
472 | self.infer_block_opt(e.loop_body())?; | 709 | self.infer_block_opt(e.loop_body(), &Expectation::has_type(Ty::unit()))?; |
473 | // TODO always unit? | 710 | // TODO always unit? |
474 | Ty::Unknown | 711 | Ty::unit() |
475 | } | 712 | } |
476 | ast::Expr::ForExpr(e) => { | 713 | ast::Expr::ForExpr(e) => { |
477 | let _iterable_ty = self.infer_expr_opt(e.iterable()); | 714 | let _iterable_ty = self.infer_expr_opt(e.iterable(), &Expectation::none()); |
478 | if let Some(_pat) = e.pat() { | 715 | if let Some(_pat) = e.pat() { |
479 | // TODO write type for pat | 716 | // TODO write type for pat |
480 | } | 717 | } |
481 | self.infer_block_opt(e.loop_body())?; | 718 | self.infer_block_opt(e.loop_body(), &Expectation::has_type(Ty::unit()))?; |
482 | // TODO always unit? | 719 | // TODO always unit? |
483 | Ty::Unknown | 720 | Ty::unit() |
484 | } | 721 | } |
485 | ast::Expr::LambdaExpr(e) => { | 722 | ast::Expr::LambdaExpr(e) => { |
486 | let _body_ty = self.infer_expr_opt(e.body())?; | 723 | let _body_ty = self.infer_expr_opt(e.body(), &Expectation::none())?; |
487 | Ty::Unknown | 724 | Ty::Unknown |
488 | } | 725 | } |
489 | ast::Expr::CallExpr(e) => { | 726 | ast::Expr::CallExpr(e) => { |
490 | let callee_ty = self.infer_expr_opt(e.expr())?; | 727 | let callee_ty = self.infer_expr_opt(e.expr(), &Expectation::none())?; |
491 | if let Some(arg_list) = e.arg_list() { | 728 | let (arg_tys, ret_ty) = match &callee_ty { |
492 | for arg in arg_list.args() { | 729 | Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), |
493 | // TODO unify / expect argument type | ||
494 | self.infer_expr(arg)?; | ||
495 | } | ||
496 | } | ||
497 | match callee_ty { | ||
498 | Ty::FnPtr(sig) => sig.output.clone(), | ||
499 | _ => { | 730 | _ => { |
500 | // not callable | 731 | // not callable |
501 | // TODO report an error? | 732 | // TODO report an error? |
502 | Ty::Unknown | 733 | (&[][..], Ty::Unknown) |
734 | } | ||
735 | }; | ||
736 | if let Some(arg_list) = e.arg_list() { | ||
737 | for (i, arg) in arg_list.args().enumerate() { | ||
738 | self.infer_expr( | ||
739 | arg, | ||
740 | &Expectation::has_type(arg_tys.get(i).cloned().unwrap_or(Ty::Unknown)), | ||
741 | )?; | ||
503 | } | 742 | } |
504 | } | 743 | } |
744 | ret_ty | ||
505 | } | 745 | } |
506 | ast::Expr::MethodCallExpr(e) => { | 746 | ast::Expr::MethodCallExpr(e) => { |
507 | let _receiver_ty = self.infer_expr_opt(e.expr())?; | 747 | let _receiver_ty = self.infer_expr_opt(e.expr(), &Expectation::none())?; |
508 | if let Some(arg_list) = e.arg_list() { | 748 | if let Some(arg_list) = e.arg_list() { |
509 | for arg in arg_list.args() { | 749 | for arg in arg_list.args() { |
510 | // TODO unify / expect argument type | 750 | // TODO unify / expect argument type |
511 | self.infer_expr(arg)?; | 751 | self.infer_expr(arg, &Expectation::none())?; |
512 | } | 752 | } |
513 | } | 753 | } |
514 | Ty::Unknown | 754 | Ty::Unknown |
515 | } | 755 | } |
516 | ast::Expr::MatchExpr(e) => { | 756 | ast::Expr::MatchExpr(e) => { |
517 | let _ty = self.infer_expr_opt(e.expr())?; | 757 | let _ty = self.infer_expr_opt(e.expr(), &Expectation::none())?; |
518 | if let Some(match_arm_list) = e.match_arm_list() { | 758 | if let Some(match_arm_list) = e.match_arm_list() { |
519 | for arm in match_arm_list.arms() { | 759 | for arm in match_arm_list.arms() { |
520 | // TODO type the bindings in pat | 760 | // TODO type the bindings in pat |
521 | // TODO type the guard | 761 | // TODO type the guard |
522 | let _ty = self.infer_expr_opt(arm.expr())?; | 762 | let _ty = self.infer_expr_opt(arm.expr(), &Expectation::none())?; |
523 | } | 763 | } |
524 | // TODO unify all the match arm types | 764 | // TODO unify all the match arm types |
525 | Ty::Unknown | 765 | Ty::Unknown |
@@ -532,10 +772,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
532 | ast::Expr::PathExpr(e) => self.infer_path_expr(e)?.unwrap_or(Ty::Unknown), | 772 | ast::Expr::PathExpr(e) => self.infer_path_expr(e)?.unwrap_or(Ty::Unknown), |
533 | ast::Expr::ContinueExpr(_e) => Ty::Never, | 773 | ast::Expr::ContinueExpr(_e) => Ty::Never, |
534 | ast::Expr::BreakExpr(_e) => Ty::Never, | 774 | ast::Expr::BreakExpr(_e) => Ty::Never, |
535 | ast::Expr::ParenExpr(e) => self.infer_expr_opt(e.expr())?, | 775 | ast::Expr::ParenExpr(e) => self.infer_expr_opt(e.expr(), expected)?, |
536 | ast::Expr::Label(_e) => Ty::Unknown, | 776 | ast::Expr::Label(_e) => Ty::Unknown, |
537 | ast::Expr::ReturnExpr(e) => { | 777 | ast::Expr::ReturnExpr(e) => { |
538 | self.infer_expr_opt(e.expr())?; | 778 | // TODO expect return type of function |
779 | self.infer_expr_opt(e.expr(), &Expectation::none())?; | ||
539 | Ty::Never | 780 | Ty::Never |
540 | } | 781 | } |
541 | ast::Expr::MatchArmList(_) | ast::Expr::MatchArm(_) | ast::Expr::MatchGuard(_) => { | 782 | ast::Expr::MatchArmList(_) | ast::Expr::MatchArm(_) | ast::Expr::MatchGuard(_) => { |
@@ -543,11 +784,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
543 | Ty::Unknown | 784 | Ty::Unknown |
544 | } | 785 | } |
545 | ast::Expr::StructLit(e) => { | 786 | ast::Expr::StructLit(e) => { |
546 | let (ty, _variant_data) = self.resolve_variant(e.path())?; | 787 | let (ty, def_id) = self.resolve_variant(e.path())?; |
547 | if let Some(nfl) = e.named_field_list() { | 788 | if let Some(nfl) = e.named_field_list() { |
548 | for field in nfl.fields() { | 789 | for field in nfl.fields() { |
549 | // TODO unify with / expect field type | 790 | let field_ty = if let (Some(def_id), Some(nr)) = (def_id, field.name_ref()) |
550 | self.infer_expr_opt(field.expr())?; | 791 | { |
792 | self.db.type_for_field(def_id, nr.as_name())? | ||
793 | } else { | ||
794 | Ty::Unknown | ||
795 | }; | ||
796 | self.infer_expr_opt(field.expr(), &Expectation::has_type(field_ty))?; | ||
551 | } | 797 | } |
552 | } | 798 | } |
553 | ty | 799 | ty |
@@ -558,40 +804,42 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
558 | } | 804 | } |
559 | ast::Expr::IndexExpr(_e) => Ty::Unknown, | 805 | ast::Expr::IndexExpr(_e) => Ty::Unknown, |
560 | ast::Expr::FieldExpr(e) => { | 806 | ast::Expr::FieldExpr(e) => { |
561 | let receiver_ty = self.infer_expr_opt(e.expr())?; | 807 | let receiver_ty = self.infer_expr_opt(e.expr(), &Expectation::none())?; |
562 | if let Some(nr) = e.name_ref() { | 808 | if let Some(nr) = e.name_ref() { |
563 | let text = nr.text(); | 809 | let ty = match receiver_ty { |
564 | match receiver_ty { | ||
565 | Ty::Tuple(fields) => { | 810 | Ty::Tuple(fields) => { |
566 | let i = text.parse::<usize>().ok(); | 811 | let i = nr.text().parse::<usize>().ok(); |
567 | i.and_then(|i| fields.get(i).cloned()) | 812 | i.and_then(|i| fields.get(i).cloned()) |
568 | .unwrap_or(Ty::Unknown) | 813 | .unwrap_or(Ty::Unknown) |
569 | } | 814 | } |
570 | Ty::Adt { def_id, .. } => self.db.type_for_field(def_id, text)?, | 815 | Ty::Adt { def_id, .. } => self.db.type_for_field(def_id, nr.as_name())?, |
571 | _ => Ty::Unknown, | 816 | _ => Ty::Unknown, |
572 | } | 817 | }; |
818 | self.insert_type_vars(ty) | ||
573 | } else { | 819 | } else { |
574 | Ty::Unknown | 820 | Ty::Unknown |
575 | } | 821 | } |
576 | } | 822 | } |
577 | ast::Expr::TryExpr(e) => { | 823 | ast::Expr::TryExpr(e) => { |
578 | let _inner_ty = self.infer_expr_opt(e.expr())?; | 824 | let _inner_ty = self.infer_expr_opt(e.expr(), &Expectation::none())?; |
579 | Ty::Unknown | 825 | Ty::Unknown |
580 | } | 826 | } |
581 | ast::Expr::CastExpr(e) => { | 827 | ast::Expr::CastExpr(e) => { |
582 | let _inner_ty = self.infer_expr_opt(e.expr())?; | 828 | let _inner_ty = self.infer_expr_opt(e.expr(), &Expectation::none())?; |
583 | let cast_ty = Ty::from_ast_opt(self.db, &self.module, e.type_ref())?; | 829 | let cast_ty = Ty::from_ast_opt(self.db, &self.module, e.type_ref())?; |
830 | let cast_ty = self.insert_type_vars(cast_ty); | ||
584 | // TODO do the coercion... | 831 | // TODO do the coercion... |
585 | cast_ty | 832 | cast_ty |
586 | } | 833 | } |
587 | ast::Expr::RefExpr(e) => { | 834 | ast::Expr::RefExpr(e) => { |
588 | let inner_ty = self.infer_expr_opt(e.expr())?; | 835 | // TODO pass the expectation down |
836 | let inner_ty = self.infer_expr_opt(e.expr(), &Expectation::none())?; | ||
589 | let m = Mutability::from_mutable(e.is_mut()); | 837 | let m = Mutability::from_mutable(e.is_mut()); |
590 | // TODO reference coercions etc. | 838 | // TODO reference coercions etc. |
591 | Ty::Ref(Arc::new(inner_ty), m) | 839 | Ty::Ref(Arc::new(inner_ty), m) |
592 | } | 840 | } |
593 | ast::Expr::PrefixExpr(e) => { | 841 | ast::Expr::PrefixExpr(e) => { |
594 | let inner_ty = self.infer_expr_opt(e.expr())?; | 842 | let inner_ty = self.infer_expr_opt(e.expr(), &Expectation::none())?; |
595 | match e.op() { | 843 | match e.op() { |
596 | Some(PrefixOp::Deref) => { | 844 | Some(PrefixOp::Deref) => { |
597 | match inner_ty { | 845 | match inner_ty { |
@@ -609,28 +857,34 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
609 | ast::Expr::BinExpr(_e) => Ty::Unknown, | 857 | ast::Expr::BinExpr(_e) => Ty::Unknown, |
610 | ast::Expr::Literal(_e) => Ty::Unknown, | 858 | ast::Expr::Literal(_e) => Ty::Unknown, |
611 | }; | 859 | }; |
860 | // use a new type variable if we got Ty::Unknown here | ||
861 | let ty = self.insert_type_vars_shallow(ty); | ||
862 | self.unify(&ty, &expected.ty); | ||
612 | self.write_ty(expr.syntax(), ty.clone()); | 863 | self.write_ty(expr.syntax(), ty.clone()); |
613 | Ok(ty) | 864 | Ok(ty) |
614 | } | 865 | } |
615 | 866 | ||
616 | fn infer_block_opt(&mut self, node: Option<ast::Block>) -> Cancelable<Ty> { | 867 | fn infer_block_opt( |
868 | &mut self, | ||
869 | node: Option<ast::Block>, | ||
870 | expected: &Expectation, | ||
871 | ) -> Cancelable<Ty> { | ||
617 | if let Some(b) = node { | 872 | if let Some(b) = node { |
618 | self.infer_block(b) | 873 | self.infer_block(b, expected) |
619 | } else { | 874 | } else { |
620 | Ok(Ty::Unknown) | 875 | Ok(Ty::Unknown) |
621 | } | 876 | } |
622 | } | 877 | } |
623 | 878 | ||
624 | fn infer_block(&mut self, node: ast::Block) -> Cancelable<Ty> { | 879 | fn infer_block(&mut self, node: ast::Block, expected: &Expectation) -> Cancelable<Ty> { |
625 | for stmt in node.statements() { | 880 | for stmt in node.statements() { |
626 | match stmt { | 881 | match stmt { |
627 | ast::Stmt::LetStmt(stmt) => { | 882 | ast::Stmt::LetStmt(stmt) => { |
628 | let decl_ty = Ty::from_ast_opt(self.db, &self.module, stmt.type_ref())?; | 883 | let decl_ty = Ty::from_ast_opt(self.db, &self.module, stmt.type_ref())?; |
884 | let decl_ty = self.insert_type_vars(decl_ty); | ||
629 | let ty = if let Some(expr) = stmt.initializer() { | 885 | let ty = if let Some(expr) = stmt.initializer() { |
630 | // TODO pass expectation | 886 | let expr_ty = self.infer_expr(expr, &Expectation::has_type(decl_ty))?; |
631 | let expr_ty = self.infer_expr(expr)?; | 887 | expr_ty |
632 | self.unify_with_coercion(&expr_ty, &decl_ty) | ||
633 | .unwrap_or(decl_ty) | ||
634 | } else { | 888 | } else { |
635 | decl_ty | 889 | decl_ty |
636 | }; | 890 | }; |
@@ -640,12 +894,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
640 | }; | 894 | }; |
641 | } | 895 | } |
642 | ast::Stmt::ExprStmt(expr_stmt) => { | 896 | ast::Stmt::ExprStmt(expr_stmt) => { |
643 | self.infer_expr_opt(expr_stmt.expr())?; | 897 | self.infer_expr_opt(expr_stmt.expr(), &Expectation::none())?; |
644 | } | 898 | } |
645 | } | 899 | } |
646 | } | 900 | } |
647 | let ty = if let Some(expr) = node.expr() { | 901 | let ty = if let Some(expr) = node.expr() { |
648 | self.infer_expr(expr)? | 902 | self.infer_expr(expr, expected)? |
649 | } else { | 903 | } else { |
650 | Ty::unit() | 904 | Ty::unit() |
651 | }; | 905 | }; |
@@ -654,7 +908,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
654 | } | 908 | } |
655 | } | 909 | } |
656 | 910 | ||
657 | pub fn infer(db: &impl HirDatabase, function: Function) -> Cancelable<InferenceResult> { | 911 | pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceResult>> { |
912 | let function = Function::new(def_id); // TODO: consts also need inference | ||
658 | let scopes = function.scopes(db); | 913 | let scopes = function.scopes(db); |
659 | let module = function.module(db)?; | 914 | let module = function.module(db)?; |
660 | let mut ctx = InferenceContext::new(db, scopes, module); | 915 | let mut ctx = InferenceContext::new(db, scopes, module); |
@@ -671,25 +926,27 @@ pub fn infer(db: &impl HirDatabase, function: Function) -> Cancelable<InferenceR | |||
671 | }; | 926 | }; |
672 | if let Some(type_ref) = param.type_ref() { | 927 | if let Some(type_ref) = param.type_ref() { |
673 | let ty = Ty::from_ast(db, &ctx.module, type_ref)?; | 928 | let ty = Ty::from_ast(db, &ctx.module, type_ref)?; |
929 | let ty = ctx.insert_type_vars(ty); | ||
674 | ctx.type_of.insert(LocalSyntaxPtr::new(pat.syntax()), ty); | 930 | ctx.type_of.insert(LocalSyntaxPtr::new(pat.syntax()), ty); |
675 | } else { | 931 | } else { |
676 | // TODO self param | 932 | // TODO self param |
933 | let type_var = ctx.new_type_var(); | ||
677 | ctx.type_of | 934 | ctx.type_of |
678 | .insert(LocalSyntaxPtr::new(pat.syntax()), Ty::Unknown); | 935 | .insert(LocalSyntaxPtr::new(pat.syntax()), type_var); |
679 | }; | 936 | }; |
680 | } | 937 | } |
681 | } | 938 | } |
682 | 939 | ||
683 | // TODO get Ty for node.ret_type() and pass that to infer_block as expectation | 940 | let ret_ty = if let Some(type_ref) = node.ret_type().and_then(|n| n.type_ref()) { |
684 | // (see Expectation in rustc_typeck) | 941 | let ty = Ty::from_ast(db, &ctx.module, type_ref)?; |
942 | ctx.insert_type_vars(ty) | ||
943 | } else { | ||
944 | Ty::unit() | ||
945 | }; | ||
685 | 946 | ||
686 | if let Some(block) = node.body() { | 947 | if let Some(block) = node.body() { |
687 | ctx.infer_block(block)?; | 948 | ctx.infer_block(block, &Expectation::has_type(ret_ty))?; |
688 | } | 949 | } |
689 | 950 | ||
690 | // TODO 'resolve' the types: replace inference variables by their inferred results | 951 | Ok(Arc::new(ctx.resolve_all())) |
691 | |||
692 | Ok(InferenceResult { | ||
693 | type_of: ctx.type_of, | ||
694 | }) | ||
695 | } | 952 | } |