aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-02-23 14:24:07 +0000
committerFlorian Diebold <[email protected]>2019-02-23 14:36:38 +0000
commitdcfb4ee70254ec696801cbdb22d2de2bb1c939ed (patch)
tree8d36f12550779a0d51c46d706f96a09df16059a3 /crates/ra_hir/src/ty
parent460ceb4cf2b8217abd002f8a30ef52f2aa25fee9 (diff)
Split ty.rs into several modules
It was just getting too big. We now have: - ty: the `Ty` enum and helpers - ty::infer: actual type inference - ty::lower: lowering from HIR to `Ty` - ty::op: helpers for binary operations, currently
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/infer.rs1079
-rw-r--r--crates/ra_hir/src/ty/lower.rs318
-rw-r--r--crates/ra_hir/src/ty/op.rs81
3 files changed, 1478 insertions, 0 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
new file mode 100644
index 000000000..6ee9080d3
--- /dev/null
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -0,0 +1,1079 @@
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
16use std::borrow::Cow;
17use std::iter::repeat;
18use std::ops::Index;
19use std::sync::Arc;
20use std::mem;
21
22use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError};
23use ra_arena::map::ArenaMap;
24use rustc_hash::FxHashMap;
25
26use test_utils::tested_by;
27
28use crate::{
29 Function, StructField, Path, Name,
30 FnSignature, AdtDef,
31 HirDatabase,
32 type_ref::{TypeRef, Mutability},
33 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self},
34 generics::GenericParams,
35 path::{GenericArgs, GenericArg},
36 adt::VariantDef,
37 resolve::{Resolver, Resolution},
38 nameres::Namespace
39};
40use super::{Ty, TypableDef, Substs, primitive, op};
41
42/// The entry point of type inference.
43pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
44 db.check_canceled();
45 let body = func.body(db);
46 let resolver = func.resolver(db);
47 let mut ctx = InferenceContext::new(db, body, resolver);
48
49 let signature = func.signature(db);
50 ctx.collect_fn_signature(&signature);
51
52 ctx.infer_body();
53
54 Arc::new(ctx.resolve_all())
55}
56
57/// The result of type inference: A mapping from expressions and patterns to types.
58#[derive(Clone, PartialEq, Eq, Debug)]
59pub struct InferenceResult {
60 /// For each method call expr, records the function it resolves to.
61 method_resolutions: FxHashMap<ExprId, Function>,
62 /// For each field access expr, records the field it resolves to.
63 field_resolutions: FxHashMap<ExprId, StructField>,
64 pub(super) type_of_expr: ArenaMap<ExprId, Ty>,
65 pub(super) type_of_pat: ArenaMap<PatId, Ty>,
66}
67
68impl InferenceResult {
69 pub fn method_resolution(&self, expr: ExprId) -> Option<Function> {
70 self.method_resolutions.get(&expr).map(|it| *it)
71 }
72 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> {
73 self.field_resolutions.get(&expr).map(|it| *it)
74 }
75}
76
77impl Index<ExprId> for InferenceResult {
78 type Output = Ty;
79
80 fn index(&self, expr: ExprId) -> &Ty {
81 self.type_of_expr.get(expr).unwrap_or(&Ty::Unknown)
82 }
83}
84
85impl Index<PatId> for InferenceResult {
86 type Output = Ty;
87
88 fn index(&self, pat: PatId) -> &Ty {
89 self.type_of_pat.get(pat).unwrap_or(&Ty::Unknown)
90 }
91}
92
93/// The inference context contains all information needed during type inference.
94#[derive(Clone, Debug)]
95struct InferenceContext<'a, D: HirDatabase> {
96 db: &'a D,
97 body: Arc<Body>,
98 resolver: Resolver,
99 var_unification_table: InPlaceUnificationTable<TypeVarId>,
100 method_resolutions: FxHashMap<ExprId, Function>,
101 field_resolutions: FxHashMap<ExprId, StructField>,
102 type_of_expr: ArenaMap<ExprId, Ty>,
103 type_of_pat: ArenaMap<PatId, Ty>,
104 /// The return type of the function being inferred.
105 return_ty: Ty,
106}
107
108impl<'a, D: HirDatabase> InferenceContext<'a, D> {
109 fn new(db: &'a D, body: Arc<Body>, resolver: Resolver) -> Self {
110 InferenceContext {
111 method_resolutions: FxHashMap::default(),
112 field_resolutions: FxHashMap::default(),
113 type_of_expr: ArenaMap::default(),
114 type_of_pat: ArenaMap::default(),
115 var_unification_table: InPlaceUnificationTable::new(),
116 return_ty: Ty::Unknown, // set in collect_fn_signature
117 db,
118 body,
119 resolver,
120 }
121 }
122
123 fn resolve_all(mut self) -> InferenceResult {
124 let mut tv_stack = Vec::new();
125 let mut expr_types = mem::replace(&mut self.type_of_expr, ArenaMap::default());
126 for ty in expr_types.values_mut() {
127 let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown));
128 *ty = resolved;
129 }
130 let mut pat_types = mem::replace(&mut self.type_of_pat, ArenaMap::default());
131 for ty in pat_types.values_mut() {
132 let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown));
133 *ty = resolved;
134 }
135 InferenceResult {
136 method_resolutions: self.method_resolutions,
137 field_resolutions: self.field_resolutions,
138 type_of_expr: expr_types,
139 type_of_pat: pat_types,
140 }
141 }
142
143 fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) {
144 self.type_of_expr.insert(expr, ty);
145 }
146
147 fn write_method_resolution(&mut self, expr: ExprId, func: Function) {
148 self.method_resolutions.insert(expr, func);
149 }
150
151 fn write_field_resolution(&mut self, expr: ExprId, field: StructField) {
152 self.field_resolutions.insert(expr, field);
153 }
154
155 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
156 self.type_of_pat.insert(pat, ty);
157 }
158
159 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
160 let ty = Ty::from_hir(
161 self.db,
162 // TODO use right resolver for block
163 &self.resolver,
164 type_ref,
165 );
166 let ty = self.insert_type_vars(ty);
167 ty
168 }
169
170 fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool {
171 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth))
172 }
173
174 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
175 self.unify_inner(ty1, ty2, 0)
176 }
177
178 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
179 if depth > 1000 {
180 // prevent stackoverflows
181 panic!("infinite recursion in unification");
182 }
183 if ty1 == ty2 {
184 return true;
185 }
186 // try to resolve type vars first
187 let ty1 = self.resolve_ty_shallow(ty1);
188 let ty2 = self.resolve_ty_shallow(ty2);
189 match (&*ty1, &*ty2) {
190 (Ty::Unknown, ..) => true,
191 (.., Ty::Unknown) => true,
192 (Ty::Int(t1), Ty::Int(t2)) => match (t1, t2) {
193 (primitive::UncertainIntTy::Unknown, _)
194 | (_, primitive::UncertainIntTy::Unknown) => true,
195 _ => t1 == t2,
196 },
197 (Ty::Float(t1), Ty::Float(t2)) => match (t1, t2) {
198 (primitive::UncertainFloatTy::Unknown, _)
199 | (_, primitive::UncertainFloatTy::Unknown) => true,
200 _ => t1 == t2,
201 },
202 (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2,
203 (
204 Ty::Adt { def_id: def_id1, substs: substs1, .. },
205 Ty::Adt { def_id: def_id2, substs: substs2, .. },
206 ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2, depth + 1),
207 (Ty::Slice(t1), Ty::Slice(t2)) => self.unify_inner(t1, t2, depth + 1),
208 (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => {
209 self.unify_inner(t1, t2, depth + 1)
210 }
211 (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify_inner(t1, t2, depth + 1),
212 (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true,
213 (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => {
214 ts1.iter().zip(ts2.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth + 1))
215 }
216 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2)))
217 | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2)))
218 | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => {
219 // both type vars are unknown since we tried to resolve them
220 self.var_unification_table.union(*tv1, *tv2);
221 true
222 }
223 (Ty::Infer(InferTy::TypeVar(tv)), other)
224 | (other, Ty::Infer(InferTy::TypeVar(tv)))
225 | (Ty::Infer(InferTy::IntVar(tv)), other)
226 | (other, Ty::Infer(InferTy::IntVar(tv)))
227 | (Ty::Infer(InferTy::FloatVar(tv)), other)
228 | (other, Ty::Infer(InferTy::FloatVar(tv))) => {
229 // the type var is unknown since we tried to resolve it
230 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone()));
231 true
232 }
233 _ => false,
234 }
235 }
236
237 fn new_type_var(&mut self) -> Ty {
238 Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
239 }
240
241 fn new_integer_var(&mut self) -> Ty {
242 Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
243 }
244
245 fn new_float_var(&mut self) -> Ty {
246 Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown)))
247 }
248
249 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it.
250 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
251 match ty {
252 Ty::Unknown => self.new_type_var(),
253 Ty::Int(primitive::UncertainIntTy::Unknown) => self.new_integer_var(),
254 Ty::Float(primitive::UncertainFloatTy::Unknown) => self.new_float_var(),
255 _ => ty,
256 }
257 }
258
259 fn insert_type_vars(&mut self, ty: Ty) -> Ty {
260 ty.fold(&mut |ty| self.insert_type_vars_shallow(ty))
261 }
262
263 /// Resolves the type as far as currently possible, replacing type variables
264 /// by their known types. All types returned by the infer_* functions should
265 /// be resolved as far as possible, i.e. contain no type variables with
266 /// known type.
267 fn resolve_ty_as_possible(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
268 ty.fold(&mut |ty| match ty {
269 Ty::Infer(tv) => {
270 let inner = tv.to_inner();
271 if tv_stack.contains(&inner) {
272 tested_by!(type_var_cycles_resolve_as_possible);
273 // recursive type
274 return tv.fallback_value();
275 }
276 if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() {
277 // known_ty may contain other variables that are known by now
278 tv_stack.push(inner);
279 let result = self.resolve_ty_as_possible(tv_stack, known_ty.clone());
280 tv_stack.pop();
281 result
282 } else {
283 ty
284 }
285 }
286 _ => ty,
287 })
288 }
289
290 /// If `ty` is a type variable with known type, returns that type;
291 /// otherwise, return ty.
292 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> {
293 let mut ty = Cow::Borrowed(ty);
294 // The type variable could resolve to a int/float variable. Hence try
295 // resolving up to three times; each type of variable shouldn't occur
296 // more than once
297 for i in 0..3 {
298 if i > 0 {
299 tested_by!(type_var_resolves_to_int_var);
300 }
301 match &*ty {
302 Ty::Infer(tv) => {
303 let inner = tv.to_inner();
304 match self.var_unification_table.probe_value(inner).known() {
305 Some(known_ty) => {
306 // The known_ty can't be a type var itself
307 ty = Cow::Owned(known_ty.clone());
308 }
309 _ => return ty,
310 }
311 }
312 _ => return ty,
313 }
314 }
315 log::error!("Inference variable still not resolved: {:?}", ty);
316 ty
317 }
318
319 /// Resolves the type completely; type variables without known type are
320 /// replaced by Ty::Unknown.
321 fn resolve_ty_completely(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
322 ty.fold(&mut |ty| match ty {
323 Ty::Infer(tv) => {
324 let inner = tv.to_inner();
325 if tv_stack.contains(&inner) {
326 tested_by!(type_var_cycles_resolve_completely);
327 // recursive type
328 return tv.fallback_value();
329 }
330 if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() {
331 // known_ty may contain other variables that are known by now
332 tv_stack.push(inner);
333 let result = self.resolve_ty_completely(tv_stack, known_ty.clone());
334 tv_stack.pop();
335 result
336 } else {
337 tv.fallback_value()
338 }
339 }
340 _ => ty,
341 })
342 }
343
344 fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> {
345 let resolved = resolver.resolve_path_segments(self.db, &path);
346
347 let (def, remaining_index) = resolved.into_inner();
348
349 log::debug!(
350 "path {:?} resolved to {:?} with remaining index {:?}",
351 path,
352 def,
353 remaining_index
354 );
355
356 // if the remaining_index is None, we expect the path
357 // to be fully resolved, in this case we continue with
358 // the default by attempting to `take_values´ from the resolution.
359 // Otherwise the path was partially resolved, which means
360 // we might have resolved into a type for which
361 // we may find some associated item starting at the
362 // path.segment pointed to by `remaining_index´
363 let resolved =
364 if remaining_index.is_none() { def.take_values()? } else { def.take_types()? };
365
366 match resolved {
367 Resolution::Def(def) => {
368 let typable: Option<TypableDef> = def.into();
369 let typable = typable?;
370
371 if let Some(remaining_index) = remaining_index {
372 let ty = self.db.type_for_def(typable, Namespace::Types);
373 // TODO: Keep resolving the segments
374 // if we have more segments to process
375 let segment = &path.segments[remaining_index];
376
377 log::debug!("looking for path segment: {:?}", segment);
378
379 // Attempt to find an impl_item for the type which has a name matching
380 // the current segment
381 let ty = ty.iterate_impl_items(self.db, |item| match item {
382 crate::ImplItem::Method(func) => {
383 let sig = func.signature(self.db);
384 if segment.name == *sig.name() {
385 return Some(func.ty(self.db));
386 }
387 None
388 }
389
390 // TODO: Resolve associated const
391 crate::ImplItem::Const(_) => None,
392
393 // TODO: Resolve associated types
394 crate::ImplItem::Type(_) => None,
395 });
396 ty
397 } else {
398 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
399 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs);
400 let ty = self.insert_type_vars(ty);
401 Some(ty)
402 }
403 }
404 Resolution::LocalBinding(pat) => {
405 let ty = self.type_of_pat.get(pat)?;
406 let ty = self.resolve_ty_as_possible(&mut vec![], ty.clone());
407 Some(ty)
408 }
409 Resolution::GenericParam(..) => {
410 // generic params can't refer to values... yet
411 None
412 }
413 Resolution::SelfType(_) => {
414 log::error!("path expr {:?} resolved to Self type in values ns", path);
415 None
416 }
417 }
418 }
419
420 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) {
421 let path = match path {
422 Some(path) => path,
423 None => return (Ty::Unknown, None),
424 };
425 let resolver = &self.resolver;
426 let typable: Option<TypableDef> = match resolver.resolve_path(self.db, &path).take_types() {
427 Some(Resolution::Def(def)) => def.into(),
428 Some(Resolution::LocalBinding(..)) => {
429 // this cannot happen
430 log::error!("path resolved to local binding in type ns");
431 return (Ty::Unknown, None);
432 }
433 Some(Resolution::GenericParam(..)) => {
434 // generic params can't be used in struct literals
435 return (Ty::Unknown, None);
436 }
437 Some(Resolution::SelfType(..)) => {
438 // TODO this is allowed in an impl for a struct, handle this
439 return (Ty::Unknown, None);
440 }
441 None => return (Ty::Unknown, None),
442 };
443 let def = match typable {
444 None => return (Ty::Unknown, None),
445 Some(it) => it,
446 };
447 // TODO remove the duplication between here and `Ty::from_path`?
448 let substs = Ty::substs_from_path(self.db, resolver, path, def);
449 match def {
450 TypableDef::Struct(s) => {
451 let ty = s.ty(self.db);
452 let ty = self.insert_type_vars(ty.apply_substs(substs));
453 (ty, Some(s.into()))
454 }
455 TypableDef::EnumVariant(var) => {
456 let ty = var.parent_enum(self.db).ty(self.db);
457 let ty = self.insert_type_vars(ty.apply_substs(substs));
458 (ty, Some(var.into()))
459 }
460 TypableDef::Function(_) | TypableDef::Enum(_) => (Ty::Unknown, None),
461 }
462 }
463
464 fn infer_tuple_struct_pat(
465 &mut self,
466 path: Option<&Path>,
467 subpats: &[PatId],
468 expected: &Ty,
469 ) -> Ty {
470 let (ty, def) = self.resolve_variant(path);
471
472 self.unify(&ty, expected);
473
474 let substs = ty.substs().unwrap_or_else(Substs::empty);
475
476 for (i, &subpat) in subpats.iter().enumerate() {
477 let expected_ty = def
478 .and_then(|d| d.field(self.db, &Name::tuple_field_name(i)))
479 .map_or(Ty::Unknown, |field| field.ty(self.db))
480 .subst(&substs);
481 self.infer_pat(subpat, &expected_ty);
482 }
483
484 ty
485 }
486
487 fn infer_struct_pat(&mut self, path: Option<&Path>, subpats: &[FieldPat], expected: &Ty) -> Ty {
488 let (ty, def) = self.resolve_variant(path);
489
490 self.unify(&ty, expected);
491
492 let substs = ty.substs().unwrap_or_else(Substs::empty);
493
494 for subpat in subpats {
495 let matching_field = def.and_then(|it| it.field(self.db, &subpat.name));
496 let expected_ty =
497 matching_field.map_or(Ty::Unknown, |field| field.ty(self.db)).subst(&substs);
498 self.infer_pat(subpat.pat, &expected_ty);
499 }
500
501 ty
502 }
503
504 fn infer_pat(&mut self, pat: PatId, expected: &Ty) -> Ty {
505 let body = Arc::clone(&self.body); // avoid borrow checker problem
506
507 let ty = match &body[pat] {
508 Pat::Tuple(ref args) => {
509 let expectations = match *expected {
510 Ty::Tuple(ref tuple_args) => &**tuple_args,
511 _ => &[],
512 };
513 let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown));
514
515 let inner_tys = args
516 .iter()
517 .zip(expectations_iter)
518 .map(|(&pat, ty)| self.infer_pat(pat, ty))
519 .collect::<Vec<_>>()
520 .into();
521
522 Ty::Tuple(inner_tys)
523 }
524 Pat::Ref { pat, mutability } => {
525 let expectation = match *expected {
526 Ty::Ref(ref sub_ty, exp_mut) => {
527 if *mutability != exp_mut {
528 // TODO: emit type error?
529 }
530 &**sub_ty
531 }
532 _ => &Ty::Unknown,
533 };
534 let subty = self.infer_pat(*pat, expectation);
535 Ty::Ref(subty.into(), *mutability)
536 }
537 Pat::TupleStruct { path: ref p, args: ref subpats } => {
538 self.infer_tuple_struct_pat(p.as_ref(), subpats, expected)
539 }
540 Pat::Struct { path: ref p, args: ref fields } => {
541 self.infer_struct_pat(p.as_ref(), fields, expected)
542 }
543 Pat::Path(path) => {
544 // TODO use correct resolver for the surrounding expression
545 let resolver = self.resolver.clone();
546 self.infer_path_expr(&resolver, &path).unwrap_or(Ty::Unknown)
547 }
548 Pat::Bind { mode, name: _name, subpat } => {
549 let inner_ty = if let Some(subpat) = subpat {
550 self.infer_pat(*subpat, expected)
551 } else {
552 expected.clone()
553 };
554 let inner_ty = self.insert_type_vars_shallow(inner_ty);
555
556 let bound_ty = match mode {
557 BindingAnnotation::Ref => Ty::Ref(inner_ty.clone().into(), Mutability::Shared),
558 BindingAnnotation::RefMut => Ty::Ref(inner_ty.clone().into(), Mutability::Mut),
559 BindingAnnotation::Mutable | BindingAnnotation::Unannotated => inner_ty.clone(),
560 };
561 let bound_ty = self.resolve_ty_as_possible(&mut vec![], bound_ty);
562 self.write_pat_ty(pat, bound_ty);
563 return inner_ty;
564 }
565 _ => Ty::Unknown,
566 };
567 // use a new type variable if we got Ty::Unknown here
568 let ty = self.insert_type_vars_shallow(ty);
569 self.unify(&ty, expected);
570 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
571 self.write_pat_ty(pat, ty.clone());
572 ty
573 }
574
575 fn substs_for_method_call(
576 &mut self,
577 def_generics: Option<Arc<GenericParams>>,
578 generic_args: &Option<GenericArgs>,
579 ) -> Substs {
580 let (parent_param_count, param_count) =
581 def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len()));
582 let mut substs = Vec::with_capacity(parent_param_count + param_count);
583 for _ in 0..parent_param_count {
584 substs.push(Ty::Unknown);
585 }
586 // handle provided type arguments
587 if let Some(generic_args) = generic_args {
588 // if args are provided, it should be all of them, but we can't rely on that
589 for arg in generic_args.args.iter().take(param_count) {
590 match arg {
591 GenericArg::Type(type_ref) => {
592 let ty = self.make_ty(type_ref);
593 substs.push(ty);
594 }
595 }
596 }
597 };
598 let supplied_params = substs.len();
599 for _ in supplied_params..parent_param_count + param_count {
600 substs.push(Ty::Unknown);
601 }
602 assert_eq!(substs.len(), parent_param_count + param_count);
603 Substs(substs.into())
604 }
605
606 fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
607 let body = Arc::clone(&self.body); // avoid borrow checker problem
608 let ty = match &body[tgt_expr] {
609 Expr::Missing => Ty::Unknown,
610 Expr::If { condition, then_branch, else_branch } => {
611 // if let is desugared to match, so this is always simple if
612 self.infer_expr(*condition, &Expectation::has_type(Ty::Bool));
613 let then_ty = self.infer_expr(*then_branch, expected);
614 match else_branch {
615 Some(else_branch) => {
616 self.infer_expr(*else_branch, expected);
617 }
618 None => {
619 // no else branch -> unit
620 self.unify(&then_ty, &Ty::unit()); // actually coerce
621 }
622 };
623 then_ty
624 }
625 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
626 Expr::Loop { body } => {
627 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
628 // TODO handle break with value
629 Ty::Never
630 }
631 Expr::While { condition, body } => {
632 // while let is desugared to a match loop, so this is always simple while
633 self.infer_expr(*condition, &Expectation::has_type(Ty::Bool));
634 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
635 Ty::unit()
636 }
637 Expr::For { iterable, body, pat } => {
638 let _iterable_ty = self.infer_expr(*iterable, &Expectation::none());
639 self.infer_pat(*pat, &Ty::Unknown);
640 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
641 Ty::unit()
642 }
643 Expr::Lambda { body, args, arg_types } => {
644 assert_eq!(args.len(), arg_types.len());
645
646 for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) {
647 let expected = if let Some(type_ref) = arg_type {
648 let ty = self.make_ty(type_ref);
649 ty
650 } else {
651 Ty::Unknown
652 };
653 self.infer_pat(*arg_pat, &expected);
654 }
655
656 // TODO: infer lambda type etc.
657 let _body_ty = self.infer_expr(*body, &Expectation::none());
658 Ty::Unknown
659 }
660 Expr::Call { callee, args } => {
661 let callee_ty = self.infer_expr(*callee, &Expectation::none());
662 let (param_tys, ret_ty) = match &callee_ty {
663 Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()),
664 Ty::FnDef { substs, sig, .. } => {
665 let ret_ty = sig.output.clone().subst(&substs);
666 let param_tys =
667 sig.input.iter().map(|ty| ty.clone().subst(&substs)).collect();
668 (param_tys, ret_ty)
669 }
670 _ => {
671 // not callable
672 // TODO report an error?
673 (Vec::new(), Ty::Unknown)
674 }
675 };
676 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
677 for (arg, param) in args.iter().zip(param_iter) {
678 self.infer_expr(*arg, &Expectation::has_type(param));
679 }
680 ret_ty
681 }
682 Expr::MethodCall { receiver, args, method_name, generic_args } => {
683 let receiver_ty = self.infer_expr(*receiver, &Expectation::none());
684 let resolved = receiver_ty.clone().lookup_method(self.db, method_name);
685 let (derefed_receiver_ty, method_ty, def_generics) = match resolved {
686 Some((ty, func)) => {
687 self.write_method_resolution(tgt_expr, func);
688 (
689 ty,
690 self.db.type_for_def(func.into(), Namespace::Values),
691 Some(func.generic_params(self.db)),
692 )
693 }
694 None => (Ty::Unknown, receiver_ty, None),
695 };
696 let substs = self.substs_for_method_call(def_generics, generic_args);
697 let method_ty = method_ty.apply_substs(substs);
698 let method_ty = self.insert_type_vars(method_ty);
699 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty {
700 Ty::FnPtr(sig) => {
701 if !sig.input.is_empty() {
702 (sig.input[0].clone(), sig.input[1..].to_vec(), sig.output.clone())
703 } else {
704 (Ty::Unknown, Vec::new(), sig.output.clone())
705 }
706 }
707 Ty::FnDef { substs, sig, .. } => {
708 let ret_ty = sig.output.clone().subst(&substs);
709
710 if !sig.input.is_empty() {
711 let mut arg_iter = sig.input.iter().map(|ty| ty.clone().subst(&substs));
712 let receiver_ty = arg_iter.next().unwrap();
713 (receiver_ty, arg_iter.collect(), ret_ty)
714 } else {
715 (Ty::Unknown, Vec::new(), ret_ty)
716 }
717 }
718 _ => (Ty::Unknown, Vec::new(), Ty::Unknown),
719 };
720 // Apply autoref so the below unification works correctly
721 let actual_receiver_ty = match expected_receiver_ty {
722 Ty::Ref(_, mutability) => Ty::Ref(Arc::new(derefed_receiver_ty), mutability),
723 _ => derefed_receiver_ty,
724 };
725 self.unify(&expected_receiver_ty, &actual_receiver_ty);
726
727 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
728 for (arg, param) in args.iter().zip(param_iter) {
729 self.infer_expr(*arg, &Expectation::has_type(param));
730 }
731 ret_ty
732 }
733 Expr::Match { expr, arms } => {
734 let expected = if expected.ty == Ty::Unknown {
735 Expectation::has_type(self.new_type_var())
736 } else {
737 expected.clone()
738 };
739 let input_ty = self.infer_expr(*expr, &Expectation::none());
740
741 for arm in arms {
742 for &pat in &arm.pats {
743 let _pat_ty = self.infer_pat(pat, &input_ty);
744 }
745 if let Some(guard_expr) = arm.guard {
746 self.infer_expr(guard_expr, &Expectation::has_type(Ty::Bool));
747 }
748 self.infer_expr(arm.expr, &expected);
749 }
750
751 expected.ty
752 }
753 Expr::Path(p) => {
754 // TODO this could be more efficient...
755 let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr);
756 self.infer_path_expr(&resolver, p).unwrap_or(Ty::Unknown)
757 }
758 Expr::Continue => Ty::Never,
759 Expr::Break { expr } => {
760 if let Some(expr) = expr {
761 // TODO handle break with value
762 self.infer_expr(*expr, &Expectation::none());
763 }
764 Ty::Never
765 }
766 Expr::Return { expr } => {
767 if let Some(expr) = expr {
768 self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone()));
769 }
770 Ty::Never
771 }
772 Expr::StructLit { path, fields, spread } => {
773 let (ty, def_id) = self.resolve_variant(path.as_ref());
774 let substs = ty.substs().unwrap_or_else(Substs::empty);
775 for field in fields {
776 let field_ty = def_id
777 .and_then(|it| it.field(self.db, &field.name))
778 .map_or(Ty::Unknown, |field| field.ty(self.db))
779 .subst(&substs);
780 self.infer_expr(field.expr, &Expectation::has_type(field_ty));
781 }
782 if let Some(expr) = spread {
783 self.infer_expr(*expr, &Expectation::has_type(ty.clone()));
784 }
785 ty
786 }
787 Expr::Field { expr, name } => {
788 let receiver_ty = self.infer_expr(*expr, &Expectation::none());
789 let ty = receiver_ty
790 .autoderef(self.db)
791 .find_map(|derefed_ty| match derefed_ty {
792 Ty::Tuple(fields) => {
793 let i = name.to_string().parse::<usize>().ok();
794 i.and_then(|i| fields.get(i).cloned())
795 }
796 Ty::Adt { def_id: AdtDef::Struct(s), ref substs, .. } => {
797 s.field(self.db, name).map(|field| {
798 self.write_field_resolution(tgt_expr, field);
799 field.ty(self.db).subst(substs)
800 })
801 }
802 _ => None,
803 })
804 .unwrap_or(Ty::Unknown);
805 self.insert_type_vars(ty)
806 }
807 Expr::Try { expr } => {
808 let _inner_ty = self.infer_expr(*expr, &Expectation::none());
809 Ty::Unknown
810 }
811 Expr::Cast { expr, type_ref } => {
812 let _inner_ty = self.infer_expr(*expr, &Expectation::none());
813 let cast_ty = self.make_ty(type_ref);
814 // TODO check the cast...
815 cast_ty
816 }
817 Expr::Ref { expr, mutability } => {
818 let expectation = if let Ty::Ref(ref subty, expected_mutability) = expected.ty {
819 if expected_mutability == Mutability::Mut && *mutability == Mutability::Shared {
820 // TODO: throw type error - expected mut reference but found shared ref,
821 // which cannot be coerced
822 }
823 Expectation::has_type((**subty).clone())
824 } else {
825 Expectation::none()
826 };
827 // TODO reference coercions etc.
828 let inner_ty = self.infer_expr(*expr, &expectation);
829 Ty::Ref(Arc::new(inner_ty), *mutability)
830 }
831 Expr::UnaryOp { expr, op } => {
832 let inner_ty = self.infer_expr(*expr, &Expectation::none());
833 match op {
834 UnaryOp::Deref => {
835 if let Some(derefed_ty) = inner_ty.builtin_deref() {
836 derefed_ty
837 } else {
838 // TODO Deref::deref
839 Ty::Unknown
840 }
841 }
842 UnaryOp::Neg => {
843 match inner_ty {
844 Ty::Int(primitive::UncertainIntTy::Unknown)
845 | Ty::Int(primitive::UncertainIntTy::Signed(..))
846 | Ty::Infer(InferTy::IntVar(..))
847 | Ty::Infer(InferTy::FloatVar(..))
848 | Ty::Float(..) => inner_ty,
849 // TODO: resolve ops::Neg trait
850 _ => Ty::Unknown,
851 }
852 }
853 UnaryOp::Not => {
854 match inner_ty {
855 Ty::Bool | Ty::Int(_) | Ty::Infer(InferTy::IntVar(..)) => inner_ty,
856 // TODO: resolve ops::Not trait for inner_ty
857 _ => Ty::Unknown,
858 }
859 }
860 }
861 }
862 Expr::BinaryOp { lhs, rhs, op } => match op {
863 Some(op) => {
864 let lhs_expectation = match op {
865 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => {
866 Expectation::has_type(Ty::Bool)
867 }
868 _ => Expectation::none(),
869 };
870 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
871 // TODO: find implementation of trait corresponding to operation
872 // symbol and resolve associated `Output` type
873 let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty);
874 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation));
875
876 // TODO: similar as above, return ty is often associated trait type
877 op::binary_op_return_ty(*op, rhs_ty)
878 }
879 _ => Ty::Unknown,
880 },
881 Expr::Tuple { exprs } => {
882 let mut ty_vec = Vec::with_capacity(exprs.len());
883 for arg in exprs.iter() {
884 ty_vec.push(self.infer_expr(*arg, &Expectation::none()));
885 }
886
887 Ty::Tuple(Arc::from(ty_vec))
888 }
889 Expr::Array { exprs } => {
890 let elem_ty = match &expected.ty {
891 Ty::Slice(inner) | Ty::Array(inner) => Ty::clone(&inner),
892 _ => self.new_type_var(),
893 };
894
895 for expr in exprs.iter() {
896 self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone()));
897 }
898
899 Ty::Array(Arc::new(elem_ty))
900 }
901 Expr::Literal(lit) => match lit {
902 Literal::Bool(..) => Ty::Bool,
903 Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared),
904 Literal::ByteString(..) => {
905 let byte_type = Arc::new(Ty::Int(primitive::UncertainIntTy::Unsigned(
906 primitive::UintTy::U8,
907 )));
908 let slice_type = Arc::new(Ty::Slice(byte_type));
909 Ty::Ref(slice_type, Mutability::Shared)
910 }
911 Literal::Char(..) => Ty::Char,
912 Literal::Int(_v, ty) => Ty::Int(*ty),
913 Literal::Float(_v, ty) => Ty::Float(*ty),
914 },
915 };
916 // use a new type variable if we got Ty::Unknown here
917 let ty = self.insert_type_vars_shallow(ty);
918 self.unify(&ty, &expected.ty);
919 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
920 self.write_expr_ty(tgt_expr, ty.clone());
921 ty
922 }
923
924 fn infer_block(
925 &mut self,
926 statements: &[Statement],
927 tail: Option<ExprId>,
928 expected: &Expectation,
929 ) -> Ty {
930 for stmt in statements {
931 match stmt {
932 Statement::Let { pat, type_ref, initializer } => {
933 let decl_ty =
934 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown);
935 let decl_ty = self.insert_type_vars(decl_ty);
936 let ty = if let Some(expr) = initializer {
937 let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty));
938 expr_ty
939 } else {
940 decl_ty
941 };
942
943 self.infer_pat(*pat, &ty);
944 }
945 Statement::Expr(expr) => {
946 self.infer_expr(*expr, &Expectation::none());
947 }
948 }
949 }
950 let ty = if let Some(expr) = tail { self.infer_expr(expr, expected) } else { Ty::unit() };
951 ty
952 }
953
954 fn collect_fn_signature(&mut self, signature: &FnSignature) {
955 let body = Arc::clone(&self.body); // avoid borrow checker problem
956 for (type_ref, pat) in signature.params().iter().zip(body.params()) {
957 let ty = self.make_ty(type_ref);
958
959 self.infer_pat(*pat, &ty);
960 }
961 self.return_ty = self.make_ty(signature.ret_type());
962 }
963
964 fn infer_body(&mut self) {
965 self.infer_expr(self.body.body_expr(), &Expectation::has_type(self.return_ty.clone()));
966 }
967}
968
969/// The ID of a type variable.
970#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
971pub struct TypeVarId(u32);
972
973impl UnifyKey for TypeVarId {
974 type Value = TypeVarValue;
975
976 fn index(&self) -> u32 {
977 self.0
978 }
979
980 fn from_index(i: u32) -> Self {
981 TypeVarId(i)
982 }
983
984 fn tag() -> &'static str {
985 "TypeVarId"
986 }
987}
988
989/// The value of a type variable: either we already know the type, or we don't
990/// know it yet.
991#[derive(Clone, PartialEq, Eq, Debug)]
992pub enum TypeVarValue {
993 Known(Ty),
994 Unknown,
995}
996
997impl TypeVarValue {
998 fn known(&self) -> Option<&Ty> {
999 match self {
1000 TypeVarValue::Known(ty) => Some(ty),
1001 TypeVarValue::Unknown => None,
1002 }
1003 }
1004}
1005
1006impl UnifyValue for TypeVarValue {
1007 type Error = NoError;
1008
1009 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> {
1010 match (value1, value2) {
1011 // We should never equate two type variables, both of which have
1012 // known types. Instead, we recursively equate those types.
1013 (TypeVarValue::Known(t1), TypeVarValue::Known(t2)) => panic!(
1014 "equating two type variables, both of which have known types: {:?} and {:?}",
1015 t1, t2
1016 ),
1017
1018 // If one side is known, prefer that one.
1019 (TypeVarValue::Known(..), TypeVarValue::Unknown) => Ok(value1.clone()),
1020 (TypeVarValue::Unknown, TypeVarValue::Known(..)) => Ok(value2.clone()),
1021
1022 (TypeVarValue::Unknown, TypeVarValue::Unknown) => Ok(TypeVarValue::Unknown),
1023 }
1024 }
1025}
1026
1027/// The kinds of placeholders we need during type inference. There's separate
1028/// values for general types, and for integer and float variables. The latter
1029/// two are used for inference of literal values (e.g. `100` could be one of
1030/// several integer types).
1031#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1032pub enum InferTy {
1033 TypeVar(TypeVarId),
1034 IntVar(TypeVarId),
1035 FloatVar(TypeVarId),
1036}
1037
1038impl InferTy {
1039 fn to_inner(self) -> TypeVarId {
1040 match self {
1041 InferTy::TypeVar(ty) | InferTy::IntVar(ty) | InferTy::FloatVar(ty) => ty,
1042 }
1043 }
1044
1045 fn fallback_value(self) -> Ty {
1046 match self {
1047 InferTy::TypeVar(..) => Ty::Unknown,
1048 InferTy::IntVar(..) => {
1049 Ty::Int(primitive::UncertainIntTy::Signed(primitive::IntTy::I32))
1050 }
1051 InferTy::FloatVar(..) => {
1052 Ty::Float(primitive::UncertainFloatTy::Known(primitive::FloatTy::F64))
1053 }
1054 }
1055 }
1056}
1057
1058/// When inferring an expression, we propagate downward whatever type hint we
1059/// are able in the form of an `Expectation`.
1060#[derive(Clone, PartialEq, Eq, Debug)]
1061struct Expectation {
1062 ty: Ty,
1063 // TODO: In some cases, we need to be aware whether the expectation is that
1064 // the type match exactly what we passed, or whether it just needs to be
1065 // coercible to the expected type. See Expectation::rvalue_hint in rustc.
1066}
1067
1068impl Expectation {
1069 /// The expectation that the type of the expression needs to equal the given
1070 /// type.
1071 fn has_type(ty: Ty) -> Self {
1072 Expectation { ty }
1073 }
1074
1075 /// This expresses no expectation on the type.
1076 fn none() -> Self {
1077 Expectation { ty: Ty::Unknown }
1078 }
1079}
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
new file mode 100644
index 000000000..cc9e0fd40
--- /dev/null
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -0,0 +1,318 @@
1//! Methods for lowering the HIR to types. There are two main cases here:
2//!
3//! - Lowering a type reference like `&usize` or `Option<foo::bar::Baz>` to a
4//! type: The entry point for this is `Ty::from_hir`.
5//! - Building the type for an item: This happens through the `type_for_def` query.
6//!
7//! This usually involves resolving names, collecting generic arguments etc.
8
9use std::sync::Arc;
10
11use crate::{
12 Function, Struct, StructField, Enum, EnumVariant, Path, Name,
13 ModuleDef,
14 HirDatabase,
15 type_ref::TypeRef,
16 name::KnownName,
17 nameres::Namespace,
18 resolve::{Resolver, Resolution},
19 path::GenericArg,
20 generics::GenericParams,
21 adt::VariantDef,
22};
23use super::{Ty, primitive, FnSig, Substs};
24
25impl Ty {
26 pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self {
27 match type_ref {
28 TypeRef::Never => Ty::Never,
29 TypeRef::Tuple(inner) => {
30 let inner_tys =
31 inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
32 Ty::Tuple(inner_tys.into())
33 }
34 TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path),
35 TypeRef::RawPtr(inner, mutability) => {
36 let inner_ty = Ty::from_hir(db, resolver, inner);
37 Ty::RawPtr(Arc::new(inner_ty), *mutability)
38 }
39 TypeRef::Array(inner) => {
40 let inner_ty = Ty::from_hir(db, resolver, inner);
41 Ty::Array(Arc::new(inner_ty))
42 }
43 TypeRef::Slice(inner) => {
44 let inner_ty = Ty::from_hir(db, resolver, inner);
45 Ty::Slice(Arc::new(inner_ty))
46 }
47 TypeRef::Reference(inner, mutability) => {
48 let inner_ty = Ty::from_hir(db, resolver, inner);
49 Ty::Ref(Arc::new(inner_ty), *mutability)
50 }
51 TypeRef::Placeholder => Ty::Unknown,
52 TypeRef::Fn(params) => {
53 let mut inner_tys =
54 params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
55 let return_ty =
56 inner_tys.pop().expect("TypeRef::Fn should always have at least return type");
57 let sig = FnSig { input: inner_tys, output: return_ty };
58 Ty::FnPtr(Arc::new(sig))
59 }
60 TypeRef::Error => Ty::Unknown,
61 }
62 }
63
64 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self {
65 if let Some(name) = path.as_ident() {
66 // TODO handle primitive type names in resolver as well?
67 if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) {
68 return Ty::Int(int_ty);
69 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) {
70 return Ty::Float(float_ty);
71 } else if let Some(known) = name.as_known_name() {
72 match known {
73 KnownName::Bool => return Ty::Bool,
74 KnownName::Char => return Ty::Char,
75 KnownName::Str => return Ty::Str,
76 _ => {}
77 }
78 }
79 }
80
81 // Resolve the path (in type namespace)
82 let resolution = resolver.resolve_path(db, path).take_types();
83
84 let def = match resolution {
85 Some(Resolution::Def(def)) => def,
86 Some(Resolution::LocalBinding(..)) => {
87 // this should never happen
88 panic!("path resolved to local binding in type ns");
89 }
90 Some(Resolution::GenericParam(idx)) => {
91 return Ty::Param {
92 idx,
93 // TODO: maybe return name in resolution?
94 name: path
95 .as_ident()
96 .expect("generic param should be single-segment path")
97 .clone(),
98 };
99 }
100 Some(Resolution::SelfType(impl_block)) => {
101 return impl_block.target_ty(db);
102 }
103 None => return Ty::Unknown,
104 };
105
106 let typable: TypableDef = match def.into() {
107 None => return Ty::Unknown,
108 Some(it) => it,
109 };
110 let ty = db.type_for_def(typable, Namespace::Types);
111 let substs = Ty::substs_from_path(db, resolver, path, typable);
112 ty.apply_substs(substs)
113 }
114
115 /// Collect generic arguments from a path into a `Substs`. See also
116 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
117 pub(super) fn substs_from_path(
118 db: &impl HirDatabase,
119 resolver: &Resolver,
120 path: &Path,
121 resolved: TypableDef,
122 ) -> Substs {
123 let mut substs = Vec::new();
124 let last = path.segments.last().expect("path should have at least one segment");
125 let (def_generics, segment) = match resolved {
126 TypableDef::Function(func) => (func.generic_params(db), last),
127 TypableDef::Struct(s) => (s.generic_params(db), last),
128 TypableDef::Enum(e) => (e.generic_params(db), last),
129 TypableDef::EnumVariant(var) => {
130 // the generic args for an enum variant may be either specified
131 // on the segment referring to the enum, or on the segment
132 // referring to the variant. So `Option::<T>::None` and
133 // `Option::None::<T>` are both allowed (though the former is
134 // preferred). See also `def_ids_for_path_segments` in rustc.
135 let len = path.segments.len();
136 let segment = if len >= 2 && path.segments[len - 2].args_and_bindings.is_some() {
137 // Option::<T>::None
138 &path.segments[len - 2]
139 } else {
140 // Option::None::<T>
141 last
142 };
143 (var.parent_enum(db).generic_params(db), segment)
144 }
145 };
146 let parent_param_count = def_generics.count_parent_params();
147 substs.extend((0..parent_param_count).map(|_| Ty::Unknown));
148 if let Some(generic_args) = &segment.args_and_bindings {
149 // if args are provided, it should be all of them, but we can't rely on that
150 let param_count = def_generics.params.len();
151 for arg in generic_args.args.iter().take(param_count) {
152 match arg {
153 GenericArg::Type(type_ref) => {
154 let ty = Ty::from_hir(db, resolver, type_ref);
155 substs.push(ty);
156 }
157 }
158 }
159 }
160 // add placeholders for args that were not provided
161 // TODO: handle defaults
162 let supplied_params = substs.len();
163 for _ in supplied_params..def_generics.count_params_including_parent() {
164 substs.push(Ty::Unknown);
165 }
166 assert_eq!(substs.len(), def_generics.count_params_including_parent());
167 Substs(substs.into())
168 }
169}
170
171/// Build the declared type of an item. This depends on the namespace; e.g. for
172/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
173/// the constructor function `(usize) -> Foo` which lives in the values
174/// namespace.
175pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty {
176 match (def, ns) {
177 (TypableDef::Function(f), Namespace::Values) => type_for_fn(db, f),
178 (TypableDef::Struct(s), Namespace::Types) => type_for_struct(db, s),
179 (TypableDef::Struct(s), Namespace::Values) => type_for_struct_constructor(db, s),
180 (TypableDef::Enum(e), Namespace::Types) => type_for_enum(db, e),
181 (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v),
182
183 // 'error' cases:
184 (TypableDef::Function(_), Namespace::Types) => Ty::Unknown,
185 (TypableDef::Enum(_), Namespace::Values) => Ty::Unknown,
186 (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown,
187 }
188}
189
190/// Build the type of a specific field of a struct or enum variant.
191pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
192 let parent_def = field.parent_def(db);
193 let resolver = match parent_def {
194 VariantDef::Struct(it) => it.resolver(db),
195 VariantDef::EnumVariant(it) => it.parent_enum(db).resolver(db),
196 };
197 let var_data = parent_def.variant_data(db);
198 let type_ref = &var_data.fields().unwrap()[field.id].type_ref;
199 Ty::from_hir(db, &resolver, type_ref)
200}
201
202/// Build the declared type of a function. This should not need to look at the
203/// function body.
204fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
205 let signature = def.signature(db);
206 let resolver = def.resolver(db);
207 let generics = def.generic_params(db);
208 let name = def.name(db);
209 let input =
210 signature.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
211 let output = Ty::from_hir(db, &resolver, signature.ret_type());
212 let sig = Arc::new(FnSig { input, output });
213 let substs = make_substs(&generics);
214 Ty::FnDef { def: def.into(), sig, name, substs }
215}
216
217/// Build the type of a tuple struct constructor.
218fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
219 let var_data = def.variant_data(db);
220 let fields = match var_data.fields() {
221 Some(fields) => fields,
222 None => return type_for_struct(db, def), // Unit struct
223 };
224 let resolver = def.resolver(db);
225 let generics = def.generic_params(db);
226 let name = def.name(db).unwrap_or_else(Name::missing);
227 let input = fields
228 .iter()
229 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
230 .collect::<Vec<_>>();
231 let output = type_for_struct(db, def);
232 let sig = Arc::new(FnSig { input, output });
233 let substs = make_substs(&generics);
234 Ty::FnDef { def: def.into(), sig, name, substs }
235}
236
237/// Build the type of a tuple enum variant constructor.
238fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
239 let var_data = def.variant_data(db);
240 let fields = match var_data.fields() {
241 Some(fields) => fields,
242 None => return type_for_enum(db, def.parent_enum(db)), // Unit variant
243 };
244 let resolver = def.parent_enum(db).resolver(db);
245 let generics = def.parent_enum(db).generic_params(db);
246 let name = def.name(db).unwrap_or_else(Name::missing);
247 let input = fields
248 .iter()
249 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
250 .collect::<Vec<_>>();
251 let substs = make_substs(&generics);
252 let output = type_for_enum(db, def.parent_enum(db)).apply_substs(substs.clone());
253 let sig = Arc::new(FnSig { input, output });
254 Ty::FnDef { def: def.into(), sig, name, substs }
255}
256
257fn make_substs(generics: &GenericParams) -> Substs {
258 Substs(
259 generics
260 .params_including_parent()
261 .into_iter()
262 .map(|p| Ty::Param { idx: p.idx, name: p.name.clone() })
263 .collect::<Vec<_>>()
264 .into(),
265 )
266}
267
268fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
269 let generics = s.generic_params(db);
270 Ty::Adt {
271 def_id: s.into(),
272 name: s.name(db).unwrap_or_else(Name::missing),
273 substs: make_substs(&generics),
274 }
275}
276
277fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
278 let generics = s.generic_params(db);
279 Ty::Adt {
280 def_id: s.into(),
281 name: s.name(db).unwrap_or_else(Name::missing),
282 substs: make_substs(&generics),
283 }
284}
285
286#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
287pub enum TypableDef {
288 Function(Function),
289 Struct(Struct),
290 Enum(Enum),
291 EnumVariant(EnumVariant),
292}
293impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant);
294
295impl From<ModuleDef> for Option<TypableDef> {
296 fn from(def: ModuleDef) -> Option<TypableDef> {
297 let res = match def {
298 ModuleDef::Function(f) => f.into(),
299 ModuleDef::Struct(s) => s.into(),
300 ModuleDef::Enum(e) => e.into(),
301 ModuleDef::EnumVariant(v) => v.into(),
302 ModuleDef::Const(_)
303 | ModuleDef::Static(_)
304 | ModuleDef::Module(_)
305 | ModuleDef::Trait(_)
306 | ModuleDef::Type(_) => return None,
307 };
308 Some(res)
309 }
310}
311
312#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
313pub enum CallableDef {
314 Function(Function),
315 Struct(Struct),
316 EnumVariant(EnumVariant),
317}
318impl_froms!(CallableDef: Function, Struct, EnumVariant);
diff --git a/crates/ra_hir/src/ty/op.rs b/crates/ra_hir/src/ty/op.rs
new file mode 100644
index 000000000..8703cf236
--- /dev/null
+++ b/crates/ra_hir/src/ty/op.rs
@@ -0,0 +1,81 @@
1use crate::expr::BinaryOp;
2use super::{Ty, InferTy};
3
4pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
5 match op {
6 BinaryOp::BooleanOr
7 | BinaryOp::BooleanAnd
8 | BinaryOp::EqualityTest
9 | BinaryOp::NegatedEqualityTest
10 | BinaryOp::LesserEqualTest
11 | BinaryOp::GreaterEqualTest
12 | BinaryOp::LesserTest
13 | BinaryOp::GreaterTest => Ty::Bool,
14 BinaryOp::Assignment
15 | BinaryOp::AddAssign
16 | BinaryOp::SubAssign
17 | BinaryOp::DivAssign
18 | BinaryOp::MulAssign
19 | BinaryOp::RemAssign
20 | BinaryOp::ShrAssign
21 | BinaryOp::ShlAssign
22 | BinaryOp::BitAndAssign
23 | BinaryOp::BitOrAssign
24 | BinaryOp::BitXorAssign => Ty::unit(),
25 BinaryOp::Addition
26 | BinaryOp::Subtraction
27 | BinaryOp::Multiplication
28 | BinaryOp::Division
29 | BinaryOp::Remainder
30 | BinaryOp::LeftShift
31 | BinaryOp::RightShift
32 | BinaryOp::BitwiseAnd
33 | BinaryOp::BitwiseOr
34 | BinaryOp::BitwiseXor => match rhs_ty {
35 Ty::Int(..)
36 | Ty::Float(..)
37 | Ty::Infer(InferTy::IntVar(..))
38 | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty,
39 _ => Ty::Unknown,
40 },
41 BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown,
42 }
43}
44
45pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
46 match op {
47 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool,
48 BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty {
49 Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty,
50 _ => Ty::Unknown,
51 },
52 BinaryOp::LesserEqualTest
53 | BinaryOp::GreaterEqualTest
54 | BinaryOp::LesserTest
55 | BinaryOp::GreaterTest
56 | BinaryOp::AddAssign
57 | BinaryOp::SubAssign
58 | BinaryOp::DivAssign
59 | BinaryOp::MulAssign
60 | BinaryOp::RemAssign
61 | BinaryOp::ShrAssign
62 | BinaryOp::ShlAssign
63 | BinaryOp::BitAndAssign
64 | BinaryOp::BitOrAssign
65 | BinaryOp::BitXorAssign
66 | BinaryOp::Addition
67 | BinaryOp::Subtraction
68 | BinaryOp::Multiplication
69 | BinaryOp::Division
70 | BinaryOp::Remainder
71 | BinaryOp::LeftShift
72 | BinaryOp::RightShift
73 | BinaryOp::BitwiseAnd
74 | BinaryOp::BitwiseOr
75 | BinaryOp::BitwiseXor => match lhs_ty {
76 Ty::Int(..) | Ty::Float(..) => lhs_ty,
77 _ => Ty::Unknown,
78 },
79 _ => Ty::Unknown,
80 }
81}