diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer.rs')
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs | 723 |
1 files changed, 723 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs new file mode 100644 index 000000000..1e9f4b208 --- /dev/null +++ b/crates/ra_hir_ty/src/infer.rs | |||
@@ -0,0 +1,723 @@ | |||
1 | //! Type inference, i.e. the process of walking through the code and determining | ||
2 | //! the type of each expression and pattern. | ||
3 | //! | ||
4 | //! For type inference, compare the implementations in rustc (the various | ||
5 | //! check_* methods in librustc_typeck/check/mod.rs are a good entry point) and | ||
6 | //! IntelliJ-Rust (org.rust.lang.core.types.infer). Our entry point for | ||
7 | //! inference here is the `infer` function, which infers the types of all | ||
8 | //! expressions in a given function. | ||
9 | //! | ||
10 | //! During inference, types (i.e. the `Ty` struct) can contain type 'variables' | ||
11 | //! which represent currently unknown types; as we walk through the expressions, | ||
12 | //! we might determine that certain variables need to be equal to each other, or | ||
13 | //! to certain types. To record this, we use the union-find implementation from | ||
14 | //! the `ena` crate, which is extracted from rustc. | ||
15 | |||
16 | use std::borrow::Cow; | ||
17 | use std::mem; | ||
18 | use std::ops::Index; | ||
19 | use std::sync::Arc; | ||
20 | |||
21 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | ||
22 | use rustc_hash::FxHashMap; | ||
23 | |||
24 | use hir_def::{ | ||
25 | body::Body, | ||
26 | data::{ConstData, FunctionData}, | ||
27 | expr::{BindingAnnotation, ExprId, PatId}, | ||
28 | path::{known, Path}, | ||
29 | resolver::{HasResolver, Resolver, TypeNs}, | ||
30 | type_ref::{Mutability, TypeRef}, | ||
31 | AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId, | ||
32 | }; | ||
33 | use hir_expand::{diagnostics::DiagnosticSink, name}; | ||
34 | use ra_arena::map::ArenaMap; | ||
35 | use ra_prof::profile; | ||
36 | use test_utils::tested_by; | ||
37 | |||
38 | use super::{ | ||
39 | primitive::{FloatTy, IntTy}, | ||
40 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | ||
41 | ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, | ||
42 | TypeWalk, Uncertain, | ||
43 | }; | ||
44 | use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; | ||
45 | |||
46 | macro_rules! ty_app { | ||
47 | ($ctor:pat, $param:pat) => { | ||
48 | crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param }) | ||
49 | }; | ||
50 | ($ctor:pat) => { | ||
51 | ty_app!($ctor, _) | ||
52 | }; | ||
53 | } | ||
54 | |||
55 | mod unify; | ||
56 | mod path; | ||
57 | mod expr; | ||
58 | mod pat; | ||
59 | mod coerce; | ||
60 | |||
61 | /// The entry point of type inference. | ||
62 | pub fn infer_query(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> { | ||
63 | let _p = profile("infer_query"); | ||
64 | let resolver = def.resolver(db); | ||
65 | let mut ctx = InferenceContext::new(db, def, resolver); | ||
66 | |||
67 | match def { | ||
68 | DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)), | ||
69 | DefWithBodyId::FunctionId(f) => ctx.collect_fn(&db.function_data(f)), | ||
70 | DefWithBodyId::StaticId(s) => ctx.collect_const(&db.static_data(s)), | ||
71 | } | ||
72 | |||
73 | ctx.infer_body(); | ||
74 | |||
75 | Arc::new(ctx.resolve_all()) | ||
76 | } | ||
77 | |||
78 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] | ||
79 | enum ExprOrPatId { | ||
80 | ExprId(ExprId), | ||
81 | PatId(PatId), | ||
82 | } | ||
83 | |||
84 | impl_froms!(ExprOrPatId: ExprId, PatId); | ||
85 | |||
86 | /// Binding modes inferred for patterns. | ||
87 | /// https://doc.rust-lang.org/reference/patterns.html#binding-modes | ||
88 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||
89 | enum BindingMode { | ||
90 | Move, | ||
91 | Ref(Mutability), | ||
92 | } | ||
93 | |||
94 | impl BindingMode { | ||
95 | pub fn convert(annotation: BindingAnnotation) -> BindingMode { | ||
96 | match annotation { | ||
97 | BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move, | ||
98 | BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared), | ||
99 | BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut), | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | |||
104 | impl Default for BindingMode { | ||
105 | fn default() -> Self { | ||
106 | BindingMode::Move | ||
107 | } | ||
108 | } | ||
109 | |||
110 | /// A mismatch between an expected and an inferred type. | ||
111 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
112 | pub struct TypeMismatch { | ||
113 | pub expected: Ty, | ||
114 | pub actual: Ty, | ||
115 | } | ||
116 | |||
117 | /// The result of type inference: A mapping from expressions and patterns to types. | ||
118 | #[derive(Clone, PartialEq, Eq, Debug, Default)] | ||
119 | pub struct InferenceResult { | ||
120 | /// For each method call expr, records the function it resolves to. | ||
121 | method_resolutions: FxHashMap<ExprId, FunctionId>, | ||
122 | /// For each field access expr, records the field it resolves to. | ||
123 | field_resolutions: FxHashMap<ExprId, StructFieldId>, | ||
124 | /// For each field in record literal, records the field it resolves to. | ||
125 | record_field_resolutions: FxHashMap<ExprId, StructFieldId>, | ||
126 | /// For each struct literal, records the variant it resolves to. | ||
127 | variant_resolutions: FxHashMap<ExprOrPatId, VariantId>, | ||
128 | /// For each associated item record what it resolves to | ||
129 | assoc_resolutions: FxHashMap<ExprOrPatId, AssocItemId>, | ||
130 | diagnostics: Vec<InferenceDiagnostic>, | ||
131 | pub type_of_expr: ArenaMap<ExprId, Ty>, | ||
132 | pub type_of_pat: ArenaMap<PatId, Ty>, | ||
133 | pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, | ||
134 | } | ||
135 | |||
136 | impl InferenceResult { | ||
137 | pub fn method_resolution(&self, expr: ExprId) -> Option<FunctionId> { | ||
138 | self.method_resolutions.get(&expr).copied() | ||
139 | } | ||
140 | pub fn field_resolution(&self, expr: ExprId) -> Option<StructFieldId> { | ||
141 | self.field_resolutions.get(&expr).copied() | ||
142 | } | ||
143 | pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructFieldId> { | ||
144 | self.record_field_resolutions.get(&expr).copied() | ||
145 | } | ||
146 | pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> { | ||
147 | self.variant_resolutions.get(&id.into()).copied() | ||
148 | } | ||
149 | pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> { | ||
150 | self.variant_resolutions.get(&id.into()).copied() | ||
151 | } | ||
152 | pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<AssocItemId> { | ||
153 | self.assoc_resolutions.get(&id.into()).copied() | ||
154 | } | ||
155 | pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<AssocItemId> { | ||
156 | self.assoc_resolutions.get(&id.into()).copied() | ||
157 | } | ||
158 | pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { | ||
159 | self.type_mismatches.get(expr) | ||
160 | } | ||
161 | pub fn add_diagnostics( | ||
162 | &self, | ||
163 | db: &impl HirDatabase, | ||
164 | owner: FunctionId, | ||
165 | sink: &mut DiagnosticSink, | ||
166 | ) { | ||
167 | self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink)) | ||
168 | } | ||
169 | } | ||
170 | |||
171 | impl Index<ExprId> for InferenceResult { | ||
172 | type Output = Ty; | ||
173 | |||
174 | fn index(&self, expr: ExprId) -> &Ty { | ||
175 | self.type_of_expr.get(expr).unwrap_or(&Ty::Unknown) | ||
176 | } | ||
177 | } | ||
178 | |||
179 | impl Index<PatId> for InferenceResult { | ||
180 | type Output = Ty; | ||
181 | |||
182 | fn index(&self, pat: PatId) -> &Ty { | ||
183 | self.type_of_pat.get(pat).unwrap_or(&Ty::Unknown) | ||
184 | } | ||
185 | } | ||
186 | |||
187 | /// The inference context contains all information needed during type inference. | ||
188 | #[derive(Clone, Debug)] | ||
189 | struct InferenceContext<'a, D: HirDatabase> { | ||
190 | db: &'a D, | ||
191 | owner: DefWithBodyId, | ||
192 | body: Arc<Body>, | ||
193 | resolver: Resolver, | ||
194 | var_unification_table: InPlaceUnificationTable<TypeVarId>, | ||
195 | trait_env: Arc<TraitEnvironment>, | ||
196 | obligations: Vec<Obligation>, | ||
197 | result: InferenceResult, | ||
198 | /// The return type of the function being inferred. | ||
199 | return_ty: Ty, | ||
200 | |||
201 | /// Impls of `CoerceUnsized` used in coercion. | ||
202 | /// (from_ty_ctor, to_ty_ctor) => coerce_generic_index | ||
203 | // FIXME: Use trait solver for this. | ||
204 | // Chalk seems unable to work well with builtin impl of `Unsize` now. | ||
205 | coerce_unsized_map: FxHashMap<(TypeCtor, TypeCtor), usize>, | ||
206 | } | ||
207 | |||
208 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | ||
209 | fn new(db: &'a D, owner: DefWithBodyId, resolver: Resolver) -> Self { | ||
210 | InferenceContext { | ||
211 | result: InferenceResult::default(), | ||
212 | var_unification_table: InPlaceUnificationTable::new(), | ||
213 | obligations: Vec::default(), | ||
214 | return_ty: Ty::Unknown, // set in collect_fn_signature | ||
215 | trait_env: TraitEnvironment::lower(db, &resolver), | ||
216 | coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), | ||
217 | db, | ||
218 | owner, | ||
219 | body: db.body(owner.into()), | ||
220 | resolver, | ||
221 | } | ||
222 | } | ||
223 | |||
224 | fn resolve_all(mut self) -> InferenceResult { | ||
225 | // FIXME resolve obligations as well (use Guidance if necessary) | ||
226 | let mut result = mem::replace(&mut self.result, InferenceResult::default()); | ||
227 | let mut tv_stack = Vec::new(); | ||
228 | for ty in result.type_of_expr.values_mut() { | ||
229 | let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown)); | ||
230 | *ty = resolved; | ||
231 | } | ||
232 | for ty in result.type_of_pat.values_mut() { | ||
233 | let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown)); | ||
234 | *ty = resolved; | ||
235 | } | ||
236 | result | ||
237 | } | ||
238 | |||
239 | fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) { | ||
240 | self.result.type_of_expr.insert(expr, ty); | ||
241 | } | ||
242 | |||
243 | fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId) { | ||
244 | self.result.method_resolutions.insert(expr, func); | ||
245 | } | ||
246 | |||
247 | fn write_field_resolution(&mut self, expr: ExprId, field: StructFieldId) { | ||
248 | self.result.field_resolutions.insert(expr, field); | ||
249 | } | ||
250 | |||
251 | fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) { | ||
252 | self.result.variant_resolutions.insert(id, variant); | ||
253 | } | ||
254 | |||
255 | fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId) { | ||
256 | self.result.assoc_resolutions.insert(id, item.into()); | ||
257 | } | ||
258 | |||
259 | fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { | ||
260 | self.result.type_of_pat.insert(pat, ty); | ||
261 | } | ||
262 | |||
263 | fn push_diagnostic(&mut self, diagnostic: InferenceDiagnostic) { | ||
264 | self.result.diagnostics.push(diagnostic); | ||
265 | } | ||
266 | |||
267 | fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { | ||
268 | let ty = Ty::from_hir( | ||
269 | self.db, | ||
270 | // FIXME use right resolver for block | ||
271 | &self.resolver, | ||
272 | type_ref, | ||
273 | ); | ||
274 | let ty = self.insert_type_vars(ty); | ||
275 | self.normalize_associated_types_in(ty) | ||
276 | } | ||
277 | |||
278 | fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool { | ||
279 | substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) | ||
280 | } | ||
281 | |||
282 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { | ||
283 | self.unify_inner(ty1, ty2, 0) | ||
284 | } | ||
285 | |||
286 | fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { | ||
287 | if depth > 1000 { | ||
288 | // prevent stackoverflows | ||
289 | panic!("infinite recursion in unification"); | ||
290 | } | ||
291 | if ty1 == ty2 { | ||
292 | return true; | ||
293 | } | ||
294 | // try to resolve type vars first | ||
295 | let ty1 = self.resolve_ty_shallow(ty1); | ||
296 | let ty2 = self.resolve_ty_shallow(ty2); | ||
297 | match (&*ty1, &*ty2) { | ||
298 | (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { | ||
299 | self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) | ||
300 | } | ||
301 | _ => self.unify_inner_trivial(&ty1, &ty2), | ||
302 | } | ||
303 | } | ||
304 | |||
305 | fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty) -> bool { | ||
306 | match (ty1, ty2) { | ||
307 | (Ty::Unknown, _) | (_, Ty::Unknown) => true, | ||
308 | |||
309 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) | ||
310 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | ||
311 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) | ||
312 | | ( | ||
313 | Ty::Infer(InferTy::MaybeNeverTypeVar(tv1)), | ||
314 | Ty::Infer(InferTy::MaybeNeverTypeVar(tv2)), | ||
315 | ) => { | ||
316 | // both type vars are unknown since we tried to resolve them | ||
317 | self.var_unification_table.union(*tv1, *tv2); | ||
318 | true | ||
319 | } | ||
320 | |||
321 | // The order of MaybeNeverTypeVar matters here. | ||
322 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. | ||
323 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. | ||
324 | (Ty::Infer(InferTy::TypeVar(tv)), other) | ||
325 | | (other, Ty::Infer(InferTy::TypeVar(tv))) | ||
326 | | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) | ||
327 | | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) | ||
328 | | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) | ||
329 | | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) | ||
330 | | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_))) | ||
331 | | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { | ||
332 | // the type var is unknown since we tried to resolve it | ||
333 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); | ||
334 | true | ||
335 | } | ||
336 | |||
337 | _ => false, | ||
338 | } | ||
339 | } | ||
340 | |||
341 | fn new_type_var(&mut self) -> Ty { | ||
342 | Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | ||
343 | } | ||
344 | |||
345 | fn new_integer_var(&mut self) -> Ty { | ||
346 | Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | ||
347 | } | ||
348 | |||
349 | fn new_float_var(&mut self) -> Ty { | ||
350 | Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | ||
351 | } | ||
352 | |||
353 | fn new_maybe_never_type_var(&mut self) -> Ty { | ||
354 | Ty::Infer(InferTy::MaybeNeverTypeVar( | ||
355 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
356 | )) | ||
357 | } | ||
358 | |||
359 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | ||
360 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | ||
361 | match ty { | ||
362 | Ty::Unknown => self.new_type_var(), | ||
363 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(Uncertain::Unknown), .. }) => { | ||
364 | self.new_integer_var() | ||
365 | } | ||
366 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(Uncertain::Unknown), .. }) => { | ||
367 | self.new_float_var() | ||
368 | } | ||
369 | _ => ty, | ||
370 | } | ||
371 | } | ||
372 | |||
373 | fn insert_type_vars(&mut self, ty: Ty) -> Ty { | ||
374 | ty.fold(&mut |ty| self.insert_type_vars_shallow(ty)) | ||
375 | } | ||
376 | |||
377 | fn resolve_obligations_as_possible(&mut self) { | ||
378 | let obligations = mem::replace(&mut self.obligations, Vec::new()); | ||
379 | for obligation in obligations { | ||
380 | let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); | ||
381 | let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); | ||
382 | let solution = self | ||
383 | .db | ||
384 | .trait_solve(self.resolver.krate().unwrap().into(), canonicalized.value.clone()); | ||
385 | |||
386 | match solution { | ||
387 | Some(Solution::Unique(substs)) => { | ||
388 | canonicalized.apply_solution(self, substs.0); | ||
389 | } | ||
390 | Some(Solution::Ambig(Guidance::Definite(substs))) => { | ||
391 | canonicalized.apply_solution(self, substs.0); | ||
392 | self.obligations.push(obligation); | ||
393 | } | ||
394 | Some(_) => { | ||
395 | // FIXME use this when trying to resolve everything at the end | ||
396 | self.obligations.push(obligation); | ||
397 | } | ||
398 | None => { | ||
399 | // FIXME obligation cannot be fulfilled => diagnostic | ||
400 | } | ||
401 | }; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | /// Resolves the type as far as currently possible, replacing type variables | ||
406 | /// by their known types. All types returned by the infer_* functions should | ||
407 | /// be resolved as far as possible, i.e. contain no type variables with | ||
408 | /// known type. | ||
409 | fn resolve_ty_as_possible(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | ||
410 | self.resolve_obligations_as_possible(); | ||
411 | |||
412 | ty.fold(&mut |ty| match ty { | ||
413 | Ty::Infer(tv) => { | ||
414 | let inner = tv.to_inner(); | ||
415 | if tv_stack.contains(&inner) { | ||
416 | tested_by!(type_var_cycles_resolve_as_possible); | ||
417 | // recursive type | ||
418 | return tv.fallback_value(); | ||
419 | } | ||
420 | if let Some(known_ty) = | ||
421 | self.var_unification_table.inlined_probe_value(inner).known() | ||
422 | { | ||
423 | // known_ty may contain other variables that are known by now | ||
424 | tv_stack.push(inner); | ||
425 | let result = self.resolve_ty_as_possible(tv_stack, known_ty.clone()); | ||
426 | tv_stack.pop(); | ||
427 | result | ||
428 | } else { | ||
429 | ty | ||
430 | } | ||
431 | } | ||
432 | _ => ty, | ||
433 | }) | ||
434 | } | ||
435 | |||
436 | /// If `ty` is a type variable with known type, returns that type; | ||
437 | /// otherwise, return ty. | ||
438 | fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { | ||
439 | let mut ty = Cow::Borrowed(ty); | ||
440 | // The type variable could resolve to a int/float variable. Hence try | ||
441 | // resolving up to three times; each type of variable shouldn't occur | ||
442 | // more than once | ||
443 | for i in 0..3 { | ||
444 | if i > 0 { | ||
445 | tested_by!(type_var_resolves_to_int_var); | ||
446 | } | ||
447 | match &*ty { | ||
448 | Ty::Infer(tv) => { | ||
449 | let inner = tv.to_inner(); | ||
450 | match self.var_unification_table.inlined_probe_value(inner).known() { | ||
451 | Some(known_ty) => { | ||
452 | // The known_ty can't be a type var itself | ||
453 | ty = Cow::Owned(known_ty.clone()); | ||
454 | } | ||
455 | _ => return ty, | ||
456 | } | ||
457 | } | ||
458 | _ => return ty, | ||
459 | } | ||
460 | } | ||
461 | log::error!("Inference variable still not resolved: {:?}", ty); | ||
462 | ty | ||
463 | } | ||
464 | |||
465 | /// Recurses through the given type, normalizing associated types mentioned | ||
466 | /// in it by replacing them by type variables and registering obligations to | ||
467 | /// resolve later. This should be done once for every type we get from some | ||
468 | /// type annotation (e.g. from a let type annotation, field type or function | ||
469 | /// call). `make_ty` handles this already, but e.g. for field types we need | ||
470 | /// to do it as well. | ||
471 | fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { | ||
472 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); | ||
473 | ty.fold(&mut |ty| match ty { | ||
474 | Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty), | ||
475 | _ => ty, | ||
476 | }) | ||
477 | } | ||
478 | |||
479 | fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty { | ||
480 | let var = self.new_type_var(); | ||
481 | let predicate = ProjectionPredicate { projection_ty: proj_ty, ty: var.clone() }; | ||
482 | let obligation = Obligation::Projection(predicate); | ||
483 | self.obligations.push(obligation); | ||
484 | var | ||
485 | } | ||
486 | |||
487 | /// Resolves the type completely; type variables without known type are | ||
488 | /// replaced by Ty::Unknown. | ||
489 | fn resolve_ty_completely(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | ||
490 | ty.fold(&mut |ty| match ty { | ||
491 | Ty::Infer(tv) => { | ||
492 | let inner = tv.to_inner(); | ||
493 | if tv_stack.contains(&inner) { | ||
494 | tested_by!(type_var_cycles_resolve_completely); | ||
495 | // recursive type | ||
496 | return tv.fallback_value(); | ||
497 | } | ||
498 | if let Some(known_ty) = | ||
499 | self.var_unification_table.inlined_probe_value(inner).known() | ||
500 | { | ||
501 | // known_ty may contain other variables that are known by now | ||
502 | tv_stack.push(inner); | ||
503 | let result = self.resolve_ty_completely(tv_stack, known_ty.clone()); | ||
504 | tv_stack.pop(); | ||
505 | result | ||
506 | } else { | ||
507 | tv.fallback_value() | ||
508 | } | ||
509 | } | ||
510 | _ => ty, | ||
511 | }) | ||
512 | } | ||
513 | |||
514 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { | ||
515 | let path = match path { | ||
516 | Some(path) => path, | ||
517 | None => return (Ty::Unknown, None), | ||
518 | }; | ||
519 | let resolver = &self.resolver; | ||
520 | // FIXME: this should resolve assoc items as well, see this example: | ||
521 | // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 | ||
522 | match resolver.resolve_path_in_type_ns_fully(self.db, &path) { | ||
523 | Some(TypeNs::AdtId(AdtId::StructId(strukt))) => { | ||
524 | let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); | ||
525 | let ty = self.db.ty(strukt.into()); | ||
526 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | ||
527 | (ty, Some(strukt.into())) | ||
528 | } | ||
529 | Some(TypeNs::EnumVariantId(var)) => { | ||
530 | let substs = Ty::substs_from_path(self.db, resolver, path, var.into()); | ||
531 | let ty = self.db.ty(var.parent.into()); | ||
532 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | ||
533 | (ty, Some(var.into())) | ||
534 | } | ||
535 | Some(_) | None => (Ty::Unknown, None), | ||
536 | } | ||
537 | } | ||
538 | |||
539 | fn collect_const(&mut self, data: &ConstData) { | ||
540 | self.return_ty = self.make_ty(&data.type_ref); | ||
541 | } | ||
542 | |||
543 | fn collect_fn(&mut self, data: &FunctionData) { | ||
544 | let body = Arc::clone(&self.body); // avoid borrow checker problem | ||
545 | for (type_ref, pat) in data.params.iter().zip(body.params.iter()) { | ||
546 | let ty = self.make_ty(type_ref); | ||
547 | |||
548 | self.infer_pat(*pat, &ty, BindingMode::default()); | ||
549 | } | ||
550 | self.return_ty = self.make_ty(&data.ret_type); | ||
551 | } | ||
552 | |||
553 | fn infer_body(&mut self) { | ||
554 | self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); | ||
555 | } | ||
556 | |||
557 | fn resolve_into_iter_item(&self) -> Option<TypeAliasId> { | ||
558 | let path = known::std_iter_into_iterator(); | ||
559 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | ||
560 | self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE) | ||
561 | } | ||
562 | |||
563 | fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { | ||
564 | let path = known::std_ops_try(); | ||
565 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | ||
566 | self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE) | ||
567 | } | ||
568 | |||
569 | fn resolve_future_future_output(&self) -> Option<TypeAliasId> { | ||
570 | let path = known::std_future_future(); | ||
571 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | ||
572 | self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE) | ||
573 | } | ||
574 | |||
575 | fn resolve_boxed_box(&self) -> Option<AdtId> { | ||
576 | let path = known::std_boxed_box(); | ||
577 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | ||
578 | Some(struct_.into()) | ||
579 | } | ||
580 | } | ||
581 | |||
582 | /// The ID of a type variable. | ||
583 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | ||
584 | pub struct TypeVarId(pub(super) u32); | ||
585 | |||
586 | impl UnifyKey for TypeVarId { | ||
587 | type Value = TypeVarValue; | ||
588 | |||
589 | fn index(&self) -> u32 { | ||
590 | self.0 | ||
591 | } | ||
592 | |||
593 | fn from_index(i: u32) -> Self { | ||
594 | TypeVarId(i) | ||
595 | } | ||
596 | |||
597 | fn tag() -> &'static str { | ||
598 | "TypeVarId" | ||
599 | } | ||
600 | } | ||
601 | |||
602 | /// The value of a type variable: either we already know the type, or we don't | ||
603 | /// know it yet. | ||
604 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
605 | pub enum TypeVarValue { | ||
606 | Known(Ty), | ||
607 | Unknown, | ||
608 | } | ||
609 | |||
610 | impl TypeVarValue { | ||
611 | fn known(&self) -> Option<&Ty> { | ||
612 | match self { | ||
613 | TypeVarValue::Known(ty) => Some(ty), | ||
614 | TypeVarValue::Unknown => None, | ||
615 | } | ||
616 | } | ||
617 | } | ||
618 | |||
619 | impl UnifyValue for TypeVarValue { | ||
620 | type Error = NoError; | ||
621 | |||
622 | fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> { | ||
623 | match (value1, value2) { | ||
624 | // We should never equate two type variables, both of which have | ||
625 | // known types. Instead, we recursively equate those types. | ||
626 | (TypeVarValue::Known(t1), TypeVarValue::Known(t2)) => panic!( | ||
627 | "equating two type variables, both of which have known types: {:?} and {:?}", | ||
628 | t1, t2 | ||
629 | ), | ||
630 | |||
631 | // If one side is known, prefer that one. | ||
632 | (TypeVarValue::Known(..), TypeVarValue::Unknown) => Ok(value1.clone()), | ||
633 | (TypeVarValue::Unknown, TypeVarValue::Known(..)) => Ok(value2.clone()), | ||
634 | |||
635 | (TypeVarValue::Unknown, TypeVarValue::Unknown) => Ok(TypeVarValue::Unknown), | ||
636 | } | ||
637 | } | ||
638 | } | ||
639 | |||
640 | /// The kinds of placeholders we need during type inference. There's separate | ||
641 | /// values for general types, and for integer and float variables. The latter | ||
642 | /// two are used for inference of literal values (e.g. `100` could be one of | ||
643 | /// several integer types). | ||
644 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | ||
645 | pub enum InferTy { | ||
646 | TypeVar(TypeVarId), | ||
647 | IntVar(TypeVarId), | ||
648 | FloatVar(TypeVarId), | ||
649 | MaybeNeverTypeVar(TypeVarId), | ||
650 | } | ||
651 | |||
652 | impl InferTy { | ||
653 | fn to_inner(self) -> TypeVarId { | ||
654 | match self { | ||
655 | InferTy::TypeVar(ty) | ||
656 | | InferTy::IntVar(ty) | ||
657 | | InferTy::FloatVar(ty) | ||
658 | | InferTy::MaybeNeverTypeVar(ty) => ty, | ||
659 | } | ||
660 | } | ||
661 | |||
662 | fn fallback_value(self) -> Ty { | ||
663 | match self { | ||
664 | InferTy::TypeVar(..) => Ty::Unknown, | ||
665 | InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(Uncertain::Known(IntTy::i32()))), | ||
666 | InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(Uncertain::Known(FloatTy::f64()))), | ||
667 | InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), | ||
668 | } | ||
669 | } | ||
670 | } | ||
671 | |||
672 | /// When inferring an expression, we propagate downward whatever type hint we | ||
673 | /// are able in the form of an `Expectation`. | ||
674 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
675 | struct Expectation { | ||
676 | ty: Ty, | ||
677 | // FIXME: In some cases, we need to be aware whether the expectation is that | ||
678 | // the type match exactly what we passed, or whether it just needs to be | ||
679 | // coercible to the expected type. See Expectation::rvalue_hint in rustc. | ||
680 | } | ||
681 | |||
682 | impl Expectation { | ||
683 | /// The expectation that the type of the expression needs to equal the given | ||
684 | /// type. | ||
685 | fn has_type(ty: Ty) -> Self { | ||
686 | Expectation { ty } | ||
687 | } | ||
688 | |||
689 | /// This expresses no expectation on the type. | ||
690 | fn none() -> Self { | ||
691 | Expectation { ty: Ty::Unknown } | ||
692 | } | ||
693 | } | ||
694 | |||
695 | mod diagnostics { | ||
696 | use hir_def::{expr::ExprId, FunctionId, HasSource, Lookup}; | ||
697 | use hir_expand::diagnostics::DiagnosticSink; | ||
698 | |||
699 | use crate::{db::HirDatabase, diagnostics::NoSuchField}; | ||
700 | |||
701 | #[derive(Debug, PartialEq, Eq, Clone)] | ||
702 | pub(super) enum InferenceDiagnostic { | ||
703 | NoSuchField { expr: ExprId, field: usize }, | ||
704 | } | ||
705 | |||
706 | impl InferenceDiagnostic { | ||
707 | pub(super) fn add_to( | ||
708 | &self, | ||
709 | db: &impl HirDatabase, | ||
710 | owner: FunctionId, | ||
711 | sink: &mut DiagnosticSink, | ||
712 | ) { | ||
713 | match self { | ||
714 | InferenceDiagnostic::NoSuchField { expr, field } => { | ||
715 | let file = owner.lookup(db).source(db).file_id; | ||
716 | let (_, source_map) = db.body_with_source_map(owner.into()); | ||
717 | let field = source_map.field_syntax(*expr, *field); | ||
718 | sink.push(NoSuchField { file, field }) | ||
719 | } | ||
720 | } | ||
721 | } | ||
722 | } | ||
723 | } | ||